﻿//using System;
//using System.Collections.Generic;
//using System.Linq;
//using System.Text;

//namespace org.webguvenligi.NSecureImageLib.GraphicFileFormats
//{
//    public class ImageData {	
//    /**
//     * The width of the image, in pixels.
//     */
//    public int width;
//    /**
//     * The height of the image, in pixels.
//     */
//    public int height;
//    /**
//     * The color depth of the image, in bits per pixel.
//     * <p>
//     * Note that a depth of 8 or less does not necessarily
//     * mean that the image is palette indexed, or
//     * conversely that a depth greater than 8 means that
//     * the image is direct color.  Check the associated
//     * PaletteData's isDirect field for such determinations.
//     */
//    public int depth;
//    /**
//     * The scanline padding.
//     * <p>
//     * If one scanline of the image is not a multiple of
//     * this number, it will be padded with zeros until it is.
//     * </p>
//     */
//    public int scanlinePad;
//    /**
//     * The number of bytes per scanline.
//     * <p>
//     * This is a multiple of the scanline padding.
//     * </p>
//     */
//    public int bytesPerLine;
//    /**
//     * The pixel data of the image.
//     * <p>
//     * Note that for 16 bit depth images the pixel data is stored
//     * in least significant byte order; however, for 24bit and
//     * 32bit depth images the pixel data is stored in most
//     * significant byte order.
//     * </p>
//     */
//    public byte[] data;
//    /**
//     * The color table for the image.
//     */
//    public PaletteData palette;
//    /**
//     * The transparent pixel.
//     * <p>
//     * Pixels with this value are transparent.
//     * </p><p>
//     * The default is -1 which means 'no transparent pixel'.
//     * </p>
//     */
//    public int transparentPixel;
//    /**
//     * An icon-specific field containing the data from the icon mask.
//     * <p>
//     * This is a 1 bit bitmap stored with the most significant
//     * bit first.  The number of bytes per scanline is
//     * '((width + 7) / 8 + (maskPad - 1)) / maskPad * maskPad'.
//     * </p><p>
//     * The default is null which means 'no transparency mask'.
//     * </p>
//     */
//    public byte[] maskData;
//    /**
//     * An icon-specific field containing the scanline pad of the mask.
//     * <p>
//     * If one scanline of the transparency mask is not a
//     * multiple of this number, it will be padded with zeros until
//     * it is.
//     * </p>
//     */
//    public int maskPad;
	
//    /**
//     * The alpha data of the image.
//     * <p>
//     * Every pixel can have an <em>alpha blending</em> value that
//     * varies from 0, meaning fully transparent, to 255 meaning
//     * fully opaque.  The number of bytes per scanline is
//     * 'width'.
//     * </p>
//     */
//    public byte[] alphaData;
	
//    /**
//     * The global alpha value to be used for every pixel.
//     * <p>
//     * If this value is set, the <code>alphaData</code> field
//     * is ignored and when the image is rendered each pixel
//     * will be blended with the background an amount
//     * proportional to this value.
//     * </p><p>
//     * The default is -1 which means 'no global alpha value'
//     * </p>
//     */
//    public int alpha;

//    /**
//     * The type of file from which the image was read.
//     * 
//     * It is expressed as one of the following values:
//     * <dl>
//     * <dt><code>IMAGE_BMP</code></dt>
//     * <dd>Windows BMP file format, no compression</dd>
//     * <dt><code>IMAGE_BMP_RLE</code></dt>
//     * <dd>Windows BMP file format, RLE compression if appropriate</dd>
//     * <dt><code>IMAGE_GIF</code></dt>
//     * <dd>GIF file format</dd>
//     * <dt><code>IMAGE_ICO</code></dt>
//     * <dd>Windows ICO file format</dd>
//     * <dt><code>IMAGE_JPEG</code></dt>
//     * <dd>JPEG file format</dd>
//     * <dt><code>IMAGE_PNG</code></dt>
//     * <dd>PNG file format</dd>
//     * </dl>
//     */
//    public int type;

//    /**
//     * The x coordinate of the top left corner of the image
//     * within the logical screen (this field corresponds to
//     * the GIF89a Image Left Position value).
//     */
//    public int x;

//    /**
//     * The y coordinate of the top left corner of the image
//     * within the logical screen (this field corresponds to
//     * the GIF89a Image Top Position value).
//     */
//    public int y;

//    /**
//     * A description of how to dispose of the current image
//     * before displaying the next.
//     * 
//     * It is expressed as one of the following values:
//     * <dl>
//     * <dt><code>DM_UNSPECIFIED</code></dt>
//     * <dd>disposal method not specified</dd>
//     * <dt><code>DM_FILL_NONE</code></dt>
//     * <dd>do nothing - leave the image in place</dd>
//     * <dt><code>DM_FILL_BACKGROUND</code></dt>
//     * <dd>fill with the background color</dd>
//     * <dt><code>DM_FILL_PREVIOUS</code></dt>
//     * <dd>restore the previous picture</dd>
//     * </dl>
//     * (this field corresponds to the GIF89a Disposal Method value)
//     */
//    public int disposalMethod;

//    /**
//     * The time to delay before displaying the next image
//     * in an animation (this field corresponds to the GIF89a
//     * Delay Time value).
//     */
//    public int delayTime;

//    /**
//     * Arbitrary channel width data to 8-bit conversion table.
//     */
//    static byte[][] ANY_TO_EIGHT = new byte[9][];
//    static ImageData(){
//        for (int b = 0; b < 9; ++b) {
//            byte[] data = ANY_TO_EIGHT[b] = new byte[1 << b];
//            if (b == 0) continue;
//            int inc = 0;
//            for (int bit = 0x10000; (bit >>= b) != 0;) inc |= bit;
//            for (int v = 0, p = 0; v < 0x10000; v+= inc) data[p++] = (byte)(v >> 8);
//        }
//    }
//    static byte[] ONE_TO_ONE_MAPPING = ANY_TO_EIGHT[8];

//    /**
//     * Scaled 8x8 Bayer dither matrix.
//     */
//    static int[][] DITHER_MATRIX = new int[][]{
//        new int[]{ 0xfc0000, 0x7c0000, 0xdc0000, 0x5c0000, 0xf40000, 0x740000, 0xd40000, 0x540000 },
//        new int[]{ 0x3c0000, 0xbc0000, 0x1c0000, 0x9c0000, 0x340000, 0xb40000, 0x140000, 0x940000 },
//        new int[]{ 0xcc0000, 0x4c0000, 0xec0000, 0x6c0000, 0xc40000, 0x440000, 0xe40000, 0x640000 },
//        new int[]{ 0x0c0000, 0x8c0000, 0x2c0000, 0xac0000, 0x040000, 0x840000, 0x240000, 0xa40000 },
//        new int[]{ 0xf00000, 0x700000, 0xd00000, 0x500000, 0xf80000, 0x780000, 0xd80000, 0x580000 },
//        new int[]{ 0x300000, 0xb00000, 0x100000, 0x900000, 0x380000, 0xb80000, 0x180000, 0x980000 },
//        new int[]{ 0xc00000, 0x400000, 0xe00000, 0x600000, 0xc80000, 0x480000, 0xe80000, 0x680000 },
//        new int[]{ 0x000000, 0x800000, 0x200000, 0xa00000, 0x080000, 0x880000, 0x280000, 0xa80000 }
//    };

///**
// * Constructs a new, empty ImageData with the given width, height,
// * depth and palette. The data will be initialized to an (all zero)
// * array of the appropriate size.
// *
// * @param width the width of the image
// * @param height the height of the image
// * @param depth the depth of the image
// * @param palette the palette of the image (must not be null)
// *
// * @exception IllegalArgumentException <ul>
// *    <li>ERROR_INVALID_ARGUMENT - if the width or height is negative, or if the depth is not
// *        	one of 1, 2, 4, 8, 16, 24 or 32</li>
// *    <li>ERROR_NULL_ARGUMENT - if the palette is null</li>
// * </ul>
// */
//public ImageData(int width, int height, int depth, PaletteData palette) {
//    this(width, height, depth, palette,
//        4, null, 0, null,
//        null, -1, -1, SWT.IMAGE_UNDEFINED,
//        0, 0, 0, 0);
//}

///**
// * Constructs a new, empty ImageData with the given width, height,
// * depth, palette, scanlinePad and data.
// *
// * @param width the width of the image
// * @param height the height of the image
// * @param depth the depth of the image
// * @param palette the palette of the image
// * @param scanlinePad the padding of each line, in bytes
// * @param data the data of the image
// *
// * @exception IllegalArgumentException <ul>
// *    <li>ERROR_INVALID_ARGUMENT - if the width or height is negative, or if the depth is not
// *        	one of 1, 2, 4, 8, 16, 24 or 32</li>
// *    <li>ERROR_NULL_ARGUMENT - if the palette or data is null</li>
// *    <li>ERROR_CANNOT_BE_ZERO - if the scanlinePad is zero</li>
// * </ul>
// */
//public ImageData(int width, int height, int depth, PaletteData palette, int scanlinePad, byte[] data) {
//    this(width, height, depth, palette,
//        scanlinePad, checkData(data), 0, null,
//        null, -1, -1, SWT.IMAGE_UNDEFINED,
//        0, 0, 0, 0);
//}

///**
// * Constructs an <code>ImageData</code> loaded from the specified
// * input stream. Throws an error if an error occurs while loading
// * the image, or if the image has an unsupported type.  Application
// * code is still responsible for closing the input stream.
// * <p>
// * This constructor is provided for convenience when loading a single
// * image only. If the stream contains multiple images, only the first
// * one will be loaded. To load multiple images, use 
// * <code>ImageLoader.load()</code>.
// * </p><p>
// * This constructor may be used to load a resource as follows:
// * </p>
// * <pre>
// *     static ImageData loadImageData (Class clazz, String string) {
// *          InputStream stream = clazz.getResourceAsStream (string);
// *          if (stream == null) return null;
// *          ImageData imageData = null;
// *          try {
// *               imageData = new ImageData (stream);
// *          } catch (SWTException ex) {
// *          } finally {
// *               try {
// *                    stream.close ();
// *               } catch (IOException ex) {}
// *          }
// *          return imageData;
// *     }
// * </pre>
// *
// * @param stream the input stream to load the image from (must not be null)
// *
// * @exception IllegalArgumentException <ul>
// *    <li>ERROR_NULL_ARGUMENT - if the stream is null</li>
// * </ul>
// * @exception SWTException <ul>
// *    <li>ERROR_INVALID_IMAGE - if the image file contains invalid data</li>
// *    <li>ERROR_IO - if an IO error occurs while reading data</li>
// * </ul>
// *
// * @see ImageLoader#load(InputStream)
// */
//public ImageData(InputStream stream) {
//    ImageData[] data = ImageDataLoader.load(stream);
//    if (data.Length < 1) SWT.error(SWT.ERROR_INVALID_IMAGE);
//    ImageData i = data[0];
//    setAllFields(
//        i.width,
//        i.height,
//        i.depth,
//        i.scanlinePad,
//        i.bytesPerLine,
//        i.data,
//        i.palette,
//        i.transparentPixel,
//        i.maskData,
//        i.maskPad,
//        i.alphaData,
//        i.alpha,
//        i.type,
//        i.x,
//        i.y,
//        i.disposalMethod,
//        i.delayTime);
//}

///**
// * Constructs an <code>ImageData</code> loaded from a file with the
// * specified name. Throws an error if an error occurs loading the
// * image, or if the image has an unsupported type.
// * <p>
// * This constructor is provided for convenience when loading a single
// * image only. If the file contains multiple images, only the first
// * one will be loaded. To load multiple images, use 
// * <code>ImageLoader.load()</code>.
// * </p>
// *
// * @param filename the name of the file to load the image from (must not be null)
// *
// * @exception IllegalArgumentException <ul>
// *    <li>ERROR_NULL_ARGUMENT - if the file name is null</li>
// * </ul>
// * @exception SWTException <ul>
// *    <li>ERROR_INVALID_IMAGE - if the image file contains invalid data</li>
// *    <li>ERROR_IO if an IO error occurs while reading data</li>
// *    <li>ERROR_UNSUPPORTED_FORMAT - if the image file contains an unrecognized format</li>
// * </ul>
// */
//public ImageData(String filename) {
//    ImageData[] data = ImageDataLoader.load(filename);
//    if (data.Length < 1) SWT.error(SWT.ERROR_INVALID_IMAGE);
//    ImageData i = data[0];
//    setAllFields(
//        i.width,
//        i.height,
//        i.depth,
//        i.scanlinePad,
//        i.bytesPerLine,
//        i.data,
//        i.palette,
//        i.transparentPixel,
//        i.maskData,
//        i.maskPad,
//        i.alphaData,
//        i.alpha,
//        i.type,
//        i.x,
//        i.y,
//        i.disposalMethod,
//        i.delayTime);
//}

///**
// * Prevents uninitialized instances from being created outside the package.
// */
//ImageData() {
//}

///**
// * Constructs an image data by giving values for all non-computable fields.
// * <p>
// * This method is for internal use, and is not described further.
// * </p>
// */
//ImageData(
//    int width, int height, int depth, PaletteData palette,
//    int scanlinePad, byte[] data, int maskPad, byte[] maskData,
//    byte[] alphaData, int alpha, int transparentPixel, int type,
//    int x, int y, int disposalMethod, int delayTime)
//{

//    if (palette == null) SWT.error(SWT.ERROR_NULL_ARGUMENT);
//    if (!(depth == 1 || depth == 2 || depth == 4 || depth == 8
//        || depth == 16 || depth == 24 || depth == 32)) {
//        SWT.error(SWT.ERROR_INVALID_ARGUMENT);
//    }
//    if (width <= 0 || height <= 0) {
//        SWT.error(SWT.ERROR_INVALID_ARGUMENT);
//    }
//    if (scanlinePad == 0) SWT.error (SWT.ERROR_CANNOT_BE_ZERO);

//    int bytesPerLine = (((width * depth + 7) / 8) + (scanlinePad - 1))
//        / scanlinePad * scanlinePad;
//    setAllFields(
//        width,
//        height,
//        depth,
//        scanlinePad,
//        bytesPerLine,
//        data != null ? data : new byte[bytesPerLine * height],
//        palette,
//        transparentPixel,
//        maskData,
//        maskPad,
//        alphaData,
//        alpha,
//        type,
//        x,
//        y,
//        disposalMethod,
//        delayTime);
//}

///**
// * Initializes all fields in the receiver. This method must be called
// * by all public constructors to ensure that all fields are initialized
// * for a new ImageData object. If a new field is added to the class,
// * then it must be added to this method.
// * <p>
// * This method is for internal use, and is not described further.
// * </p>
// */
//void setAllFields(int width, int height, int depth, int scanlinePad,
//    int bytesPerLine, byte[] data, PaletteData palette, int transparentPixel,
//    byte[] maskData, int maskPad, byte[] alphaData, int alpha,
//    int type, int x, int y, int disposalMethod, int delayTime) {

//    this.width = width;
//    this.height = height;
//    this.depth = depth;
//    this.scanlinePad = scanlinePad;
//    this.bytesPerLine = bytesPerLine;
//    this.data = data;
//    this.palette = palette;
//    this.transparentPixel = transparentPixel;
//    this.maskData = maskData;
//    this.maskPad = maskPad;
//    this.alphaData = alphaData;
//    this.alpha = alpha;
//    this.type = type;
//    this.x = x;
//    this.y = y;
//    this.disposalMethod = disposalMethod;
//    this.delayTime = delayTime;
//}

///**	 
// * Invokes internal SWT functionality to create a new instance of
// * this class.
// * <p>
// * <b>IMPORTANT:</b> This method is <em>not</em> part of the public
// * API for <code>ImageData</code>. It is marked public only so that it
// * can be shared within the packages provided by SWT. It is subject
// * to change without notice, and should never be called from
// * application code.
// * </p>
// * <p>
// * This method is for internal use, and is not described further.
// * </p>
// */
//public static ImageData internal_new(
//    int width, int height, int depth, PaletteData palette,
//    int scanlinePad, byte[] data, int maskPad, byte[] maskData,
//    byte[] alphaData, int alpha, int transparentPixel, int type,
//    int x, int y, int disposalMethod, int delayTime)
//{
//    return new ImageData(
//        width, height, depth, palette, scanlinePad, data, maskPad, maskData,
//        alphaData, alpha, transparentPixel, type, x, y, disposalMethod, delayTime);
//}

//ImageData colorMaskImage(int pixel) {
//    ImageData mask = new ImageData(width, height, 1, bwPalette(),
//        2, null, 0, null, null, -1, -1, SWT.IMAGE_UNDEFINED,
//        0, 0, 0, 0);
//    int[] row = new int[width];
//    for (int y = 0; y < height; y++) {
//        getPixels(0, y, width, row, 0);
//        for (int i = 0; i < width; i++) {
//            if (pixel != -1 && row[i] == pixel) {
//                row[i] = 0;
//            } else {
//                row[i] = 1;
//            }
//        }
//        mask.setPixels(0, y, width, row, 0);
//    }
//    return mask;
//}

//static byte[] checkData(byte [] data) {
//    if (data == null) SWT.error(SWT.ERROR_NULL_ARGUMENT);
//    return data;
//}

///**
// * Returns a new instance of the same class as the receiver,
// * whose slots have been filled in with <em>copies</em> of
// * the values in the slots of the receiver. That is, the
// * returned object is a <em>deep copy</em> of the receiver.
// *
// * @return a copy of the receiver.
// */
//public Object clone() {
//    byte[] cloneData = new byte[data.Length];
//    System.arraycopy(data, 0, cloneData, 0, data.Length);
//    byte[] cloneMaskData = null;
//    if (maskData != null) {
//        cloneMaskData = new byte[maskData.Length];
//        System.arraycopy(maskData, 0, cloneMaskData, 0, maskData.Length);
//    }
//    byte[] cloneAlphaData = null;
//    if (alphaData != null) {
//        cloneAlphaData = new byte[alphaData.Length];
//        System.arraycopy(alphaData, 0, cloneAlphaData, 0, alphaData.Length);
//    }
//    return new ImageData(
//        width,
//        height,
//        depth,
//        palette,
//        scanlinePad,
//        cloneData,
//        maskPad,
//        cloneMaskData,
//        cloneAlphaData,
//        alpha,
//        transparentPixel,
//        type,
//        x,
//        y,
//        disposalMethod,
//        delayTime);
//}

///**
// * Returns the alpha value at offset <code>x</code> in
// * scanline <code>y</code> in the receiver's alpha data.
// *
// * @param x the x coodinate of the pixel to get the alpha value of
// * @param y the y coordinate of the pixel to get the alpha value of
// * @return the alpha value at the given coordinates
// *
// * @exception IllegalArgumentException <ul>
// *    <li>ERROR_INVALID_ARGUMENT - if either argument is out of range</li>
// * </ul>
// */
//public int getAlpha(int x, int y) {
//    if (x >= width || y >= height || x < 0 || y < 0) SWT.error(SWT.ERROR_INVALID_ARGUMENT);

//    if (alphaData == null) return 255;
//    return alphaData[y * width + x] & 0xFF;
//}

///**
// * Returns <code>getWidth</code> alpha values starting at offset
// * <code>x</code> in scanline <code>y</code> in the receiver's alpha
// * data starting at <code>startIndex</code>.
// *
// * @param x the x position of the pixel to begin getting alpha values
// * @param y the y position of the pixel to begin getting alpha values
// * @param getWidth the width of the data to get
// * @param alphas the buffer in which to put the alpha values
// * @param startIndex the offset into the image to begin getting alpha values
// *
// * @exception IndexOutOfBoundsException if getWidth is too large
// * @exception IllegalArgumentException <ul>
// *    <li>ERROR_NULL_ARGUMENT - if pixels is null</li>
// *    <li>ERROR_INVALID_ARGUMENT - if x or y is out of bounds</li>
// *    <li>ERROR_INVALID_ARGUMENT - if getWidth is negative</li>
// * </ul>
// */
//public void getAlphas(int x, int y, int getWidth, byte[] alphas, int startIndex) {
//    if (alphas == null) SWT.error(SWT.ERROR_NULL_ARGUMENT);
//    if (getWidth < 0 || x >= width || y >= height || x < 0 || y < 0) SWT.error(SWT.ERROR_INVALID_ARGUMENT);
//    if (getWidth == 0) return;

//    if (alphaData == null) {
//        int endIndex = startIndex + getWidth;
//        for (int i = startIndex; i < endIndex; i++) {
//            alphas[i] = (byte)255;
//        }
//        return;
//    }
//    // may throw an IndexOutOfBoundsException
//    System.arraycopy(alphaData, y * width + x, alphas, startIndex, getWidth);
//}

///**
// * Returns the pixel value at offset <code>x</code> in
// * scanline <code>y</code> in the receiver's data.
// *
// * @param x the x position of the pixel to get
// * @param y the y position of the pixel to get
// * @return the pixel at the given coordinates
// *
// * @exception IllegalArgumentException <ul>
// *    <li>ERROR_INVALID_ARGUMENT - if either argument is out of bounds</li>
// * </ul>
// * @exception SWTException <ul>
// *    <li>ERROR_UNSUPPORTED_DEPTH if the depth is not one of 1, 2, 4, 8, 16, 24 or 32</li>
// * </ul>
// */
//public int getPixel(int x, int y) {
//    if (x >= width || y >= height || x < 0 || y < 0) SWT.error(SWT.ERROR_INVALID_ARGUMENT);
//    int index;
//    int theByte;
//    int mask;
//    if (depth == 1) {
//        index = (y * bytesPerLine) + (x >> 3);
//        theByte = data[index] & 0xFF;
//        mask = 1 << (7 - (x & 0x7));
//        if ((theByte & mask) == 0) {
//            return 0;
//        } else {
//            return 1;
//        }
//    }
//    if (depth == 2) {
//        index = (y * bytesPerLine) + (x >> 2);
//        theByte = data[index] & 0xFF;
//        int offset = 3 - (x % 4);
//        mask = 3 << (offset * 2);
//        return (theByte & mask) >> (offset * 2);
//    }
//    if (depth == 4) {
//        index = (y * bytesPerLine) + (x >> 1);
//        theByte = data[index] & 0xFF;
//        if ((x & 0x1) == 0) {
//            return theByte >> 4;
//        } else {
//            return theByte & 0x0F;
//        }
//    }
//    if (depth == 8) {
//        index = (y * bytesPerLine) + x ;
//        return data[index] & 0xFF;
//    }
//    if (depth == 16) {
//        index = (y * bytesPerLine) + (x * 2);
//        return ((data[index+1] & 0xFF) << 8) + (data[index] & 0xFF);
//    }
//    if (depth == 24) {
//        index = (y * bytesPerLine) + (x * 3);
//        return ((data[index] & 0xFF) << 16) + ((data[index+1] & 0xFF) << 8) +
//            (data[index+2] & 0xFF);
//    }
//    if (depth == 32) {
//        index = (y * bytesPerLine) + (x * 4);
//        return ((data[index] & 0xFF) << 24) + ((data[index+1] & 0xFF) << 16) +
//                ((data[index+2] & 0xFF) << 8) + (data[index+3] & 0xFF);
//    }
//    SWT.error(SWT.ERROR_UNSUPPORTED_DEPTH);
//    return 0;
//}

///**
// * Returns <code>getWidth</code> pixel values starting at offset
// * <code>x</code> in scanline <code>y</code> in the receiver's
// * data starting at <code>startIndex</code>.
// *
// * @param x the x position of the first pixel to get
// * @param y the y position of the first pixel to get
// * @param getWidth the width of the data to get
// * @param pixels the buffer in which to put the pixels
// * @param startIndex the offset into the byte array to begin storing pixels
// *
// * @exception IndexOutOfBoundsException if getWidth is too large
// * @exception IllegalArgumentException <ul>
// *    <li>ERROR_NULL_ARGUMENT - if pixels is null</li>
// *    <li>ERROR_INVALID_ARGUMENT - if x or y is out of bounds</li>
// *    <li>ERROR_INVALID_ARGUMENT - if getWidth is negative</li>
// * </ul>
// * @exception SWTException <ul>
// *    <li>ERROR_UNSUPPORTED_DEPTH - if the depth is not one of 1, 2, 4 or 8
// *        (For higher depths, use the int[] version of this method.)</li>
// * </ul>
// */
//public void getPixels(int x, int y, int getWidth, byte[] pixels, int startIndex) {
//    if (pixels == null) SWT.error(SWT.ERROR_NULL_ARGUMENT);
//    if (getWidth < 0 || x >= width || y >= height || x < 0 || y < 0) SWT.error(SWT.ERROR_INVALID_ARGUMENT);
//    if (getWidth == 0) return;
//    int index;
//    int theByte;
//    int mask = 0;
//    int n = getWidth;
//    int i = startIndex;
//    int srcX = x, srcY = y;
//    if (depth == 1) {
//        index = (y * bytesPerLine) + (x >> 3);
//        theByte = data[index] & 0xFF;
//        while (n > 0) {
//            mask = 1 << (7 - (srcX & 0x7));
//            if ((theByte & mask) == 0) {
//                pixels[i] = 0;
//            } else {
//                pixels[i] = 1;
//            }
//            i++;
//            n--;
//            srcX++;
//            if (srcX >= width) {
//                srcY++;
//                index = srcY * bytesPerLine;
//                if (n > 0) theByte = data[index] & 0xFF;
//                srcX = 0;
//            } else {
//                if (mask == 1) {
//                    index++;
//                    if (n > 0) theByte = data[index] & 0xFF;
//                }
//            }
//        }
//        return;
//    }
//    if (depth == 2) {
//        index = (y * bytesPerLine) + (x >> 2);
//        theByte = data[index] & 0xFF;
//        int offset;
//        while (n > 0) {
//            offset = 3 - (srcX % 4);
//            mask = 3 << (offset * 2);
//            pixels[i] = (byte)((theByte & mask) >> (offset * 2));
//            i++;
//            n--;
//            srcX++;
//            if (srcX >= width) {
//                srcY++;
//                index = srcY * bytesPerLine;
//                if (n > 0) theByte = data[index] & 0xFF;
//                srcX = 0;
//            } else {
//                if (offset == 0) {
//                    index++;
//                    theByte = data[index] & 0xFF;
//                }
//            }
//        }
//        return;
//    }
//    if (depth == 4) {
//        index = (y * bytesPerLine) + (x >> 1);
//        if ((x & 0x1) == 1) {
//            theByte = data[index] & 0xFF;
//            pixels[i] = (byte)(theByte & 0x0F);
//            i++;
//            n--;
//            srcX++;
//            if (srcX >= width) {
//                srcY++;
//                index = srcY * bytesPerLine;
//                srcX = 0;
//            } else {
//                index++;
//            }
//        }
//        while (n > 1) {
//            theByte = data[index] & 0xFF;
//            pixels[i] = (byte)(theByte >> 4);
//            i++;
//            n--;
//            srcX++;
//            if (srcX >= width) {
//                srcY++;
//                index = srcY * bytesPerLine;
//                srcX = 0;
//            } else {
//                pixels[i] = (byte)(theByte & 0x0F);
//                i++;
//                n--;
//                srcX++;
//                if (srcX >= width) {
//                    srcY++;
//                    index = srcY * bytesPerLine;
//                    srcX = 0;
//                } else {
//                    index++;
//                }
//            }
//        }
//        if (n > 0) {
//            theByte = data[index] & 0xFF;
//            pixels[i] = (byte)(theByte >> 4);
//        }
//        return;
//    }
//    if (depth == 8) {
//        index = (y * bytesPerLine) + x;
//        for (int j = 0; j < getWidth; j++) {
//            pixels[i] = data[index];
//            i++;
//            srcX++;
//            if (srcX >= width) {
//                srcY++;
//                index = srcY * bytesPerLine;
//                srcX = 0;
//            } else {
//                index++;
//            }
//        }
//        return;
//    }
//    SWT.error(SWT.ERROR_UNSUPPORTED_DEPTH);
//}

///**
// * Returns <code>getWidth</code> pixel values starting at offset
// * <code>x</code> in scanline <code>y</code> in the receiver's
// * data starting at <code>startIndex</code>.
// *
// * @param x the x position of the first pixel to get
// * @param y the y position of the first pixel to get
// * @param getWidth the width of the data to get
// * @param pixels the buffer in which to put the pixels
// * @param startIndex the offset into the buffer to begin storing pixels
// *
// * @exception IndexOutOfBoundsException if getWidth is too large
// * @exception IllegalArgumentException <ul>
// *    <li>ERROR_NULL_ARGUMENT - if pixels is null</li>
// *    <li>ERROR_INVALID_ARGUMENT - if x or y is out of bounds</li>
// *    <li>ERROR_INVALID_ARGUMENT - if getWidth is negative</li>
// * </ul>
// * @exception SWTException <ul>
// *    <li>ERROR_UNSUPPORTED_DEPTH - if the depth is not one of 1, 2, 4, 8, 16, 24 or 32</li>
// * </ul>
// */
//public void getPixels(int x, int y, int getWidth, int[] pixels, int startIndex) {
//    if (pixels == null) SWT.error(SWT.ERROR_NULL_ARGUMENT);
//    if (getWidth < 0 || x >= width || y >= height || x < 0 || y < 0) SWT.error(SWT.ERROR_INVALID_ARGUMENT);
//    if (getWidth == 0) return;
//    int index;
//    int theByte;
//    int mask;
//    int n = getWidth;
//    int i = startIndex;
//    int srcX = x, srcY = y;
//    if (depth == 1) {
//        index = (y * bytesPerLine) + (x >> 3);
//        theByte = data[index] & 0xFF;
//        while (n > 0) {
//            mask = 1 << (7 - (srcX & 0x7));
//            if ((theByte & mask) == 0) {
//                pixels[i] = 0;
//            } else {
//                pixels[i] = 1;
//            }
//            i++;
//            n--;
//            srcX++;
//            if (srcX >= width) {
//                srcY++;
//                index = srcY * bytesPerLine;
//                if (n > 0) theByte = data[index] & 0xFF;
//                srcX = 0;
//            } else {
//                if (mask == 1) {
//                    index++;
//                    if (n > 0) theByte = data[index] & 0xFF;
//                }
//            }
//        }
//        return;
//    }		
//    if (depth == 2) {
//        index = (y * bytesPerLine) + (x >> 2);
//        theByte = data[index] & 0xFF;
//        int offset;
//        while (n > 0) {
//            offset = 3 - (srcX % 4);
//            mask = 3 << (offset * 2);
//            pixels[i] = (byte)((theByte & mask) >> (offset * 2));
//            i++;
//            n--;
//            srcX++;
//            if (srcX >= width) {
//                srcY++;
//                index = srcY * bytesPerLine;
//                if (n > 0) theByte = data[index] & 0xFF;
//                srcX = 0;
//            } else {
//                if (offset == 0) {
//                    index++;
//                    theByte = data[index] & 0xFF;
//                }
//            }
//        }
//        return;
//    }
//    if (depth == 4) {
//        index = (y * bytesPerLine) + (x >> 1);
//        if ((x & 0x1) == 1) {
//            theByte = data[index] & 0xFF;
//            pixels[i] = theByte & 0x0F;
//            i++;
//            n--;
//            srcX++;
//            if (srcX >= width) {
//                srcY++;
//                index = srcY * bytesPerLine;
//                srcX = 0;
//            } else {
//                index++;
//            }
//        }
//        while (n > 1) {
//            theByte = data[index] & 0xFF;
//            pixels[i] = theByte >> 4;
//            i++;
//            n--;
//            srcX++;
//            if (srcX >= width) {
//                srcY++;
//                index = srcY * bytesPerLine;
//                srcX = 0;
//            } else {
//                pixels[i] = theByte & 0x0F;
//                i++;
//                n--;
//                srcX++;
//                if (srcX >= width) {
//                    srcY++;
//                    index = srcY * bytesPerLine;
//                    srcX = 0;
//                } else {
//                    index++;
//                }
//            }
//        }
//        if (n > 0) {
//            theByte = data[index] & 0xFF;
//            pixels[i] = theByte >> 4;
//        }
//        return;
//    }
//    if (depth == 8) {
//        index = (y * bytesPerLine) + x;
//        for (int j = 0; j < getWidth; j++) {
//            pixels[i] = data[index] & 0xFF;
//            i++;
//            srcX++;
//            if (srcX >= width) {
//                srcY++;
//                index = srcY * bytesPerLine;
//                srcX = 0;
//            } else {
//                index++;
//            }
//        }
//        return;
//    }
//    if (depth == 16) {
//        index = (y * bytesPerLine) + (x * 2);
//        for (int j = 0; j < getWidth; j++) {
//            pixels[i] = ((data[index+1] & 0xFF) << 8) + (data[index] & 0xFF);
//            i++;
//            srcX++;
//            if (srcX >= width) {
//                srcY++;
//                index = srcY * bytesPerLine;
//                srcX = 0;
//            } else {
//                index += 2;
//            }
//        }
//        return;
//    }
//    if (depth == 24) {
//        index = (y * bytesPerLine) + (x * 3);
//        for (int j = 0; j < getWidth; j++) {
//            pixels[i] = ((data[index] & 0xFF) << 16) | ((data[index+1] & 0xFF) << 8)
//                | (data[index+2] & 0xFF);
//            i++;
//            srcX++;
//            if (srcX >= width) {
//                srcY++;
//                index = srcY * bytesPerLine;
//                srcX = 0;
//            } else {
//                index += 3;
//            }
//        }
//        return;
//    }
//    if (depth == 32) {
//        index = (y * bytesPerLine) + (x * 4);
//        i = startIndex;
//        for (int j = 0; j < getWidth; j++) {
//            pixels[i] = ((data[index] & 0xFF) << 24) | ((data[index+1] & 0xFF) << 16)
//                | ((data[index+2] & 0xFF) << 8) | (data[index+3] & 0xFF);
//            i++;
//            srcX++;
//            if (srcX >= width) {
//                srcY++;
//                index = srcY * bytesPerLine;
//                srcX = 0;
//            } else {
//                index += 4;
//            }
//        }
//        return;
//    }
//    SWT.error(SWT.ERROR_UNSUPPORTED_DEPTH);
//}

///**
// * Returns an array of <code>RGB</code>s which comprise the
// * indexed color table of the receiver, or null if the receiver
// * has a direct color model.
// *
// * @return the RGB values for the image or null if direct color
// *
// * @see PaletteData#getRGBs()
// */
//public RGB[] getRGBs() {
//    return palette.getRGBs();
//}

///**
// * Returns an <code>ImageData</code> which specifies the
// * transparency mask information for the receiver. If the
// * receiver has no transparency or is not an icon, returns
// * an opaque mask.
// *
// * @return the transparency mask
// */
//public ImageData getTransparencyMask() {
//    if (getTransparencyType() == SWT.TRANSPARENCY_MASK) {
//        return new ImageData(width, height, 1, bwPalette(), maskPad, maskData);
//    } else {
//        return colorMaskImage(transparentPixel);
//    }
//}

///**
// * Returns the image transparency type, which will be one of
// * <code>SWT.TRANSPARENCY_NONE</code>, <code>SWT.TRANSPARENCY_MASK</code>,
// * <code>SWT.TRANSPARENCY_PIXEL</code> or <code>SWT.TRANSPARENCY_ALPHA</code>.
// *
// * @return the receiver's transparency type
// */
//public int getTransparencyType() {
//    if (maskData != null) return SWT.TRANSPARENCY_MASK;
//    if (transparentPixel != -1) return SWT.TRANSPARENCY_PIXEL;
//    if (alphaData != null) return SWT.TRANSPARENCY_ALPHA;
//    return SWT.TRANSPARENCY_NONE;
//}

///**
// * Returns the byte order of the receiver.
// * 
// * @return MSB_FIRST or LSB_FIRST
// */
//int getByteOrder() {
//    return depth != 16 ? MSB_FIRST : LSB_FIRST;
//}

///**
// * Returns a copy of the receiver which has been stretched or
// * shrunk to the specified size. If either the width or height
// * is negative, the resulting image will be inverted in the
// * associated axis.
// *
// * @param width the width of the new ImageData
// * @param height the height of the new ImageData
// * @return a scaled copy of the image
// */
//public ImageData scaledTo(int width, int height) {
//    /* Create a destination image with no data */
//    bool flipX = (width < 0);
//    if (flipX) width = - width;
//    bool flipY = (height < 0);
//    if (flipY) height = - height;

//    ImageData dest = new ImageData(
//        width, height, depth, palette,
//        scanlinePad, null, 0, null,
//        null, -1, transparentPixel, type,
//        x, y, disposalMethod, delayTime);

//    /* Scale the image contents */
//    if (palette.isDirect) blit(BLIT_SRC,
//        this.data, this.depth, this.bytesPerLine, this.getByteOrder(), 0, 0, this.width, this.height, 0, 0, 0,
//        ALPHA_OPAQUE, null, 0, 0, 0,
//        dest.data, dest.depth, dest.bytesPerLine, dest.getByteOrder(), 0, 0, dest.width, dest.height, 0, 0, 0,
//        flipX, flipY);
//    else blit(BLIT_SRC,
//        this.data, this.depth, this.bytesPerLine, this.getByteOrder(), 0, 0, this.width, this.height, null, null, null,
//        ALPHA_OPAQUE, null, 0, 0, 0,
//        dest.data, dest.depth, dest.bytesPerLine, dest.getByteOrder(), 0, 0, dest.width, dest.height, null, null, null,
//        flipX, flipY);
	
//    /* Scale the image mask or alpha */
//    if (maskData != null) {
//        dest.maskPad = this.maskPad;
//        int destBpl = (dest.width + 7) / 8;
//        destBpl = (destBpl + (dest.maskPad - 1)) / dest.maskPad * dest.maskPad;
//        dest.maskData = new byte[destBpl * dest.height];
//        int srcBpl = (this.width + 7) / 8;
//        srcBpl = (srcBpl + (this.maskPad - 1)) / this.maskPad * this.maskPad;
//        blit(BLIT_SRC,
//            this.maskData, 1, srcBpl, MSB_FIRST, 0, 0, this.width, this.height, null, null, null,
//            ALPHA_OPAQUE, null, 0, 0, 0,
//            dest.maskData, 1, destBpl, MSB_FIRST, 0, 0, dest.width, dest.height, null, null, null,
//            flipX, flipY);
//    } else if (alpha != -1) {
//        dest.alpha = this.alpha;
//    } else if (alphaData != null) {
//        dest.alphaData = new byte[dest.width * dest.height];
//        blit(BLIT_SRC,
//            this.alphaData, 8, this.width, MSB_FIRST, 0, 0, this.width, this.height, null, null, null,
//            ALPHA_OPAQUE, null, 0, 0, 0,
//            dest.alphaData, 8, dest.width, MSB_FIRST, 0, 0, dest.width, dest.height, null, null, null,
//            flipX, flipY);
//    }
//    return dest;
//}

///**
// * Sets the alpha value at offset <code>x</code> in
// * scanline <code>y</code> in the receiver's alpha data.
// *
// * @param x the x coordinate of the alpha value to set
// * @param y the y coordinate of the alpha value to set
// * @param alpha the value to set the alpha to
// *
// * @exception IllegalArgumentException <ul>
// *    <li>ERROR_INVALID_ARGUMENT - if x or y is out of bounds</li>
// *  </ul>
// */
//public void setAlpha(int x, int y, int alpha) {
//    if (x >= width || y >= height || x < 0 || y < 0 || alpha < 0 || alpha > 255)
//        SWT.error(SWT.ERROR_INVALID_ARGUMENT);
	
//    if (alphaData == null) alphaData = new byte[width * height];
//    alphaData[y * width + x] = (byte)alpha;	
//}

///**
// * Sets the alpha values starting at offset <code>x</code> in
// * scanline <code>y</code> in the receiver's alpha data to the
// * values from the array <code>alphas</code> starting at
// * <code>startIndex</code>.
// *
// * @param x the x coordinate of the pixel to being setting the alpha values
// * @param y the y coordinate of the pixel to being setting the alpha values
// * @param putWidth the width of the alpha values to set
// * @param alphas the alpha values to set
// * @param startIndex the index at which to begin setting
// *
// * @exception IndexOutOfBoundsException if putWidth is too large
// * @exception IllegalArgumentException <ul>
// *    <li>ERROR_NULL_ARGUMENT - if pixels is null</li>
// *    <li>ERROR_INVALID_ARGUMENT - if x or y is out of bounds</li>
// *    <li>ERROR_INVALID_ARGUMENT - if putWidth is negative</li>
// * </ul>
// */
//public void setAlphas(int x, int y, int putWidth, byte[] alphas, int startIndex) {
//    if (alphas == null) SWT.error(SWT.ERROR_NULL_ARGUMENT);
//    if (putWidth < 0 || x >= width || y >= height || x < 0 || y < 0) SWT.error(SWT.ERROR_INVALID_ARGUMENT);
//    if (putWidth == 0) return;
	
//    if (alphaData == null) alphaData = new byte[width * height];
//    // may throw an IndexOutOfBoundsException
//    System.arraycopy(alphas, startIndex, alphaData, y * width + x, putWidth);
//}

///**
// * Sets the pixel value at offset <code>x</code> in
// * scanline <code>y</code> in the receiver's data.
// *
// * @param x the x coordinate of the pixel to set
// * @param y the y coordinate of the pixel to set
// * @param pixelValue the value to set the pixel to
// *
// * @exception IllegalArgumentException <ul>
// *    <li>ERROR_INVALID_ARGUMENT - if x or y is out of bounds</li>
// * </ul>
// * @exception SWTException <ul>
// *    <li>ERROR_UNSUPPORTED_DEPTH if the depth is not one of 1, 2, 4, 8, 16, 24 or 32</li>
// * </ul>
// */
//public void setPixel(int x, int y, int pixelValue) {
//    if (x >= width || y >= height || x < 0 || y < 0) SWT.error(SWT.ERROR_INVALID_ARGUMENT);
//    int index;
//    byte theByte;
//    int mask;
//    if (depth == 1) {
//        index = (y * bytesPerLine) + (x >> 3);
//        theByte = data[index];
//        mask = 1 << (7 - (x & 0x7));
//        if ((pixelValue & 0x1) == 1) {
//            data[index] = (byte)(theByte | mask);
//        } else {
//            data[index] = (byte)(theByte & (mask ^ -1));
//        }
//        return;
//    }
//    if (depth == 2) {
//        index = (y * bytesPerLine) + (x >> 2);
//        theByte = data[index];
//        int offset = 3 - (x % 4);
//        mask = 0xFF ^ (3 << (offset * 2));
//        data[index] = (byte)((data[index] & mask) | (pixelValue << (offset * 2)));
//        return;
//    }
//    if (depth == 4) {
//        index = (y * bytesPerLine) + (x >> 1);
//        if ((x & 0x1) == 0) {
//            data[index] = (byte)((data[index] & 0x0F) | ((pixelValue & 0x0F) << 4));
//        } else {
//            data[index] = (byte)((data[index] & 0xF0) | (pixelValue & 0x0F));
//        }
//        return;
//    }
//    if (depth == 8) {
//        index = (y * bytesPerLine) + x ;
//        data[index] = (byte)(pixelValue & 0xFF);
//        return;
//    }
//    if (depth == 16) {
//        index = (y * bytesPerLine) + (x * 2);
//        data[index + 1] = (byte)((pixelValue >> 8) & 0xFF);
//        data[index] = (byte)(pixelValue & 0xFF);
//        return;
//    }
//    if (depth == 24) {
//        index = (y * bytesPerLine) + (x * 3);
//        data[index] = (byte)((pixelValue >> 16) & 0xFF);
//        data[index + 1] = (byte)((pixelValue >> 8) & 0xFF);
//        data[index + 2] = (byte)(pixelValue & 0xFF);
//        return;
//    }
//    if (depth == 32) {
//        index = (y * bytesPerLine) + (x * 4);
//        data[index]  = (byte)((pixelValue >> 24) & 0xFF);
//        data[index + 1] = (byte)((pixelValue >> 16) & 0xFF);
//        data[index + 2] = (byte)((pixelValue >> 8) & 0xFF);
//        data[index + 3] = (byte)(pixelValue & 0xFF);
//        return;
//    }
//    SWT.error(SWT.ERROR_UNSUPPORTED_DEPTH);
//}

///**
// * Sets the pixel values starting at offset <code>x</code> in
// * scanline <code>y</code> in the receiver's data to the
// * values from the array <code>pixels</code> starting at
// * <code>startIndex</code>.
// *
// * @param x the x position of the pixel to set
// * @param y the y position of the pixel to set
// * @param putWidth the width of the pixels to set
// * @param pixels the pixels to set
// * @param startIndex the index at which to begin setting
// *
// * @exception IndexOutOfBoundsException if putWidth is too large
// * @exception IllegalArgumentException <ul>
// *    <li>ERROR_NULL_ARGUMENT - if pixels is null</li>
// *    <li>ERROR_INVALID_ARGUMENT - if x or y is out of bounds</li>
// *    <li>ERROR_INVALID_ARGUMENT - if putWidth is negative</li>
// * </ul>
// * @exception SWTException <ul>
// *    <li>ERROR_UNSUPPORTED_DEPTH if the depth is not one of 1, 2, 4, 8
// *        (For higher depths, use the int[] version of this method.)</li>
// * </ul>
// */
//public void setPixels(int x, int y, int putWidth, byte[] pixels, int startIndex) {
//    if (pixels == null) SWT.error(SWT.ERROR_NULL_ARGUMENT);
//    if (putWidth < 0 || x >= width || y >= height || x < 0 || y < 0) SWT.error(SWT.ERROR_INVALID_ARGUMENT);
//    if (putWidth == 0) return;
//    int index;
//    int theByte;
//    int mask;
//    int n = putWidth;
//    int i = startIndex;
//    int srcX = x, srcY = y;
//    if (depth == 1) {
//        index = (y * bytesPerLine) + (x >> 3);
//        while (n > 0) {
//            mask = 1 << (7 - (srcX & 0x7));
//            if ((pixels[i] & 0x1) == 1) {
//                data[index] = (byte)((data[index] & 0xFF) | mask);
//            } else {
//                data[index] = (byte)((data[index] & 0xFF) & (mask ^ -1));
//            }
//            i++;
//            n--;
//            srcX++;
//            if (srcX >= width) {
//                srcY++;
//                index = srcY * bytesPerLine;
//                srcX = 0;
//            } else {
//                if (mask == 1) {
//                    index++;
//                }
//            }
//        }
//        return;
//    }
//    if (depth == 2) {
//        byte [] masks = { (byte)0xFC, (byte)0xF3, (byte)0xCF, (byte)0x3F };
//        index = (y * bytesPerLine) + (x >> 2);
//        int offset = 3 - (x % 4);
//        while (n > 0) {
//            theByte = pixels[i] & 0x3;
//            data[index] = (byte)((data[index] & masks[offset]) | (theByte << (offset * 2)));
//            i++;
//            n--;
//            srcX++;
//            if (srcX >= width) {
//                srcY++;
//                index = srcY * bytesPerLine;
//                offset = 0;
//                srcX = 0;
//            } else {
//                if (offset == 0) {
//                    index++;
//                    offset = 3;
//                } else {
//                    offset--;
//                }
//            }
//        }
//        return;
//    }
//    if (depth == 4) {
//        index = (y * bytesPerLine) + (x >> 1);
//        bool high = (x & 0x1) == 0;
//        while (n > 0) {
//            theByte = pixels[i] & 0x0F;
//            if (high) {
//                data[index] = (byte)((data[index] & 0x0F) | (theByte << 4));
//            } else {
//                data[index] = (byte)((data[index] & 0xF0) | theByte);
//            }
//            i++;
//            n--;
//            srcX++;
//            if (srcX >= width) {
//                srcY++;
//                index = srcY * bytesPerLine;
//                high = true;
//                srcX = 0;
//            } else {
//                if (!high) index++;
//                high = !high;
//            }
//        }
//        return;
//    }
//    if (depth == 8) {
//        index = (y * bytesPerLine) + x;
//        for (int j = 0; j < putWidth; j++) {
//            data[index] = (byte)(pixels[i] & 0xFF);
//            i++;
//            srcX++;
//            if (srcX >= width) {
//                srcY++;
//                index = srcY * bytesPerLine;
//                srcX = 0;
//            } else {
//                index++;
//            }
//        }
//        return;
//    }
//    SWT.error(SWT.ERROR_UNSUPPORTED_DEPTH);
//}

///**
// * Sets the pixel values starting at offset <code>x</code> in
// * scanline <code>y</code> in the receiver's data to the
// * values from the array <code>pixels</code> starting at
// * <code>startIndex</code>.
// *
// * @param x the x position of the pixel to set
// * @param y the y position of the pixel to set
// * @param putWidth the width of the pixels to set
// * @param pixels the pixels to set
// * @param startIndex the index at which to begin setting
// *
// * @exception IndexOutOfBoundsException if putWidth is too large
// * @exception IllegalArgumentException <ul>
// *    <li>ERROR_NULL_ARGUMENT - if pixels is null</li>
// *    <li>ERROR_INVALID_ARGUMENT - if x or y is out of bounds</li>
// *    <li>ERROR_INVALID_ARGUMENT - if putWidth is negative</li>
// * </ul>
// * @exception SWTException <ul>
// *    <li>ERROR_UNSUPPORTED_DEPTH if the depth is not one of 1, 2, 4, 8, 16, 24 or 32</li>
// * </ul>
// */
//public void setPixels(int x, int y, int putWidth, int[] pixels, int startIndex) {
//    if (pixels == null) SWT.error(SWT.ERROR_NULL_ARGUMENT);
//    if (putWidth < 0 || x >= width || y >= height || x < 0 || y < 0) SWT.error(SWT.ERROR_INVALID_ARGUMENT);
//    if (putWidth == 0) return;
//    int index;
//    int theByte;
//    int mask;
//    int n = putWidth;
//    int i = startIndex;
//    int pixel;
//    int srcX = x, srcY = y;
//    if (depth == 1) {
//        index = (y * bytesPerLine) + (x >> 3);
//        while (n > 0) {
//            mask = 1 << (7 - (srcX & 0x7));
//            if ((pixels[i] & 0x1) == 1) {
//                data[index] = (byte)((data[index] & 0xFF) | mask);
//            } else {
//                data[index] = (byte)((data[index] & 0xFF) & (mask ^ -1));
//            }
//            i++;
//            n--;
//            srcX++;
//            if (srcX >= width) {
//                srcY++;
//                index = srcY * bytesPerLine;
//                srcX = 0;
//            } else {
//                if (mask == 1) {
//                    index++;
//                }
//            }
//        }
//        return;
//    }
//    if (depth == 2) {
//        byte [] masks = { (byte)0xFC, (byte)0xF3, (byte)0xCF, (byte)0x3F };
//        index = (y * bytesPerLine) + (x >> 2);
//        int offset = 3 - (x % 4);
//        while (n > 0) {
//            theByte = pixels[i] & 0x3;
//            data[index] = (byte)((data[index] & masks[offset]) | (theByte << (offset * 2)));
//            i++;
//            n--;
//            srcX++;
//            if (srcX >= width) {
//                srcY++;
//                index = srcY * bytesPerLine;
//                offset = 3;
//                srcX = 0;
//            } else {
//                if (offset == 0) {
//                    index++;
//                    offset = 3;
//                } else {
//                    offset--;
//                }
//            }
//        }
//        return;
//    }
//    if (depth == 4) {
//        index = (y * bytesPerLine) + (x >> 1);
//        bool high = (x & 0x1) == 0;
//        while (n > 0) {
//            theByte = pixels[i] & 0x0F;
//            if (high) {
//                data[index] = (byte)((data[index] & 0x0F) | (theByte << 4));
//            } else {
//                data[index] = (byte)((data[index] & 0xF0) | theByte);
//            }
//            i++;
//            n--;
//            srcX++;
//            if (srcX >= width) {
//                srcY++;
//                index = srcY * bytesPerLine;
//                high = true;
//                srcX = 0;
//            } else {
//                if (!high) index++;
//                high = !high;
//            }
//        }
//        return;
//    }
//    if (depth == 8) {
//        index = (y * bytesPerLine) + x;
//        for (int j = 0; j < putWidth; j++) {
//            data[index] = (byte)(pixels[i] & 0xFF);
//            i++;
//            srcX++;
//            if (srcX >= width) {
//                srcY++;
//                index = srcY * bytesPerLine;
//                srcX = 0;
//            } else {
//                index++;
//            }
//        }
//        return;

//    }
//    if (depth == 16) {
//        index = (y * bytesPerLine) + (x * 2);
//        for (int j = 0; j < putWidth; j++) {
//            pixel = pixels[i];
//            data[index] = (byte)(pixel & 0xFF);
//            data[index + 1] = (byte)((pixel >> 8) & 0xFF);
//            i++;
//            srcX++;
//            if (srcX >= width) {
//                srcY++;
//                index = srcY * bytesPerLine;
//                srcX = 0;
//            } else {
//                index += 2;
//            }
//        }
//        return;
//    }
//    if (depth == 24) {
//        index = (y * bytesPerLine) + (x * 3);
//        for (int j = 0; j < putWidth; j++) {
//            pixel = pixels[i];
//            data[index] = (byte)((pixel >> 16) & 0xFF);
//            data[index + 1] = (byte)((pixel >> 8) & 0xFF);
//            data[index + 2] = (byte)(pixel & 0xFF);
//            i++;
//            srcX++;
//            if (srcX >= width) {
//                srcY++;
//                index = srcY * bytesPerLine;
//                srcX = 0;
//            } else {
//                index += 3;
//            }
//        }
//        return;
//    }
//    if (depth == 32) {
//        index = (y * bytesPerLine) + (x * 4);
//        for (int j = 0; j < putWidth; j++) {
//            pixel = pixels[i];
//            data[index] = (byte)((pixel >> 24) & 0xFF);
//            data[index + 1] = (byte)((pixel >> 16) & 0xFF);
//            data[index + 2] = (byte)((pixel >> 8) & 0xFF);
//            data[index + 3] = (byte)(pixel & 0xFF);
//            i++;
//            srcX++;
//            if (srcX >= width) {
//                srcY++;
//                index = srcY * bytesPerLine;
//                srcX = 0;
//            } else {
//                index += 4;
//            }
//        }
//        return;
//    }
//    SWT.error(SWT.ERROR_UNSUPPORTED_DEPTH);
//}

///**
// * Returns a palette with 2 colors: black & white.
// */
//static PaletteData bwPalette() {
//    return new PaletteData(new RGB[] {new RGB(0, 0, 0), new RGB(255, 255, 255)});
//}

///**
// * Gets the offset of the most significant bit for
// * the given mask.
// */
//static int getMSBOffset(int mask) {
//    for (int i = 31; i >= 0; i--) {
//        if (((mask >> i) & 0x1) != 0) return i + 1;
//    }
//    return 0;
//}

///**
// * Finds the closest match.
// */
//static int closestMatch(int depth, byte red, byte green, byte blue, int redMask, int greenMask, int blueMask, byte[] reds, byte[] greens, byte[] blues) {
//    if (depth > 8) {
//        int rshift = 32 - getMSBOffset(redMask);
//        int gshift = 32 - getMSBOffset(greenMask);
//        int bshift = 32 - getMSBOffset(blueMask);
//        return (((red << 24) >> rshift) & redMask) |
//            (((green << 24) >> gshift) & greenMask) |
//            (((blue << 24) >> bshift) & blueMask);
//    }
//    int r, g, b;
//    int minDistance = 0x7fffffff;
//    int nearestPixel = 0;
//    int n = reds.Length;
//    for (int j = 0; j < n; j++) {
//        r = (reds[j] & 0xFF) - (red & 0xFF);
//        g = (greens[j] & 0xFF) - (green & 0xFF);
//        b = (blues[j] & 0xFF) - (blue & 0xFF);
//        int distance = r*r + g*g + b*b;
//        if (distance < minDistance) {
//            nearestPixel = j;
//            if (distance == 0) break;
//            minDistance = distance;
//        }
//    }
//    return nearestPixel;
//}

//static ImageData convertMask(ImageData mask) {
//    if (mask.depth == 1) return mask;
//    PaletteData palette = new PaletteData(new RGB[] {new RGB(0, 0, 0), new RGB(255,255,255)});
//    ImageData newMask = new ImageData(mask.width, mask.height, 1, palette);
//    /* Find index of black in mask palette */
//    int blackIndex = 0;
//    RGB[] rgbs = mask.getRGBs();
//    if (rgbs != null) {
//        while (blackIndex < rgbs.Length) {
//            if (rgbs[blackIndex].equals(palette.colors[0])) break;
//            blackIndex++;
//        }
//    }
//    int[] pixels = new int[mask.width];
//    for (int y = 0; y < mask.height; y++) {
//        mask.getPixels(0, y, mask.width, pixels, 0);
//        for (int i = 0; i < pixels.Length; i++) {
//            if (pixels[i] == blackIndex) {
//                pixels[i] = 0;
//            } else {
//                pixels[i] = 1;
//            }
//        }
//        newMask.setPixels(0, y, mask.width, pixels, 0);
//    }
//    return newMask;
//}

//static byte[] convertPad(byte[] data, int width, int height, int depth, int pad, int newPad) {
//    if (pad == newPad) return data;
//    int stride = (width * depth + 7) / 8;
//    int bpl = (stride + (pad - 1)) / pad * pad;	
//    int newBpl = (stride + (newPad - 1)) / newPad * newPad;
//    byte[] newData = new byte[height * newBpl];
//    int srcIndex = 0, destIndex = 0;
//    for (int y = 0; y < height; y++) {
//        System.arraycopy(data, srcIndex, newData, destIndex, stride);
//        srcIndex += bpl;
//        destIndex += newBpl;
//    }
//    return newData;
//}

///**
// * Blit operation bits to be OR'ed together to specify the desired operation.
// */
//static int
//    BLIT_SRC = 1,     // copy source directly, else applies logic operations
//    BLIT_ALPHA = 2,   // enable alpha blending
//    BLIT_DITHER = 4;  // enable dithering in low color modes

///**
// * Alpha mode, values 0 - 255 specify global alpha level
// */
//const int
//    ALPHA_OPAQUE = 255,           // Fully opaque (ignores any alpha data)
//    ALPHA_TRANSPARENT = 0,        // Fully transparent (ignores any alpha data)
//    ALPHA_CHANNEL_SEPARATE = -1,  // Use alpha channel from separate alphaData
//    ALPHA_CHANNEL_SOURCE = -2,    // Use alpha channel embedded in sourceData
//    ALPHA_MASK_UNPACKED = -3,     // Use transparency mask formed by bytes in alphaData (non-zero is opaque)
//    ALPHA_MASK_PACKED = -4,       // Use transparency mask formed by packed bits in alphaData
//    ALPHA_MASK_INDEX = -5,        // Consider source palette indices transparent if in alphaData array
//    ALPHA_MASK_RGB = -6;          // Consider source RGBs transparent if in RGB888 format alphaData array

///**
// * Byte and bit order constants.
// */
//static int LSB_FIRST = 0;
//static int MSB_FIRST = 1;

///**
// * Data types (internal)
// */
//private const int
//    // direct / true color formats with arbitrary masks & shifts
//    TYPE_GENERIC_8 = 0,
//    TYPE_GENERIC_16_MSB = 1,
//    TYPE_GENERIC_16_LSB = 2,
//    TYPE_GENERIC_24 = 3,
//    TYPE_GENERIC_32_MSB = 4,
//    TYPE_GENERIC_32_LSB = 5,
//    // palette indexed color formats
//    TYPE_INDEX_8 = 6,
//    TYPE_INDEX_4 = 7,
//    TYPE_INDEX_2 = 8,
//    TYPE_INDEX_1_MSB = 9,
//    TYPE_INDEX_1_LSB = 10;

///**
// * Blits a direct palette image into a direct palette image.
// * <p>
// * Note: When the source and destination depth, order and masks
// * are pairwise equal and the blitter operation is BLIT_SRC,
// * the masks are ignored.  Hence when not changing the image
// * data format, 0 may be specified for the masks.
// * </p>
// * 
// * @param op the blitter operation: a combination of BLIT_xxx flags
// *        (see BLIT_xxx constants)
// * @param srcData the source byte array containing image data
// * @param srcDepth the source depth: one of 8, 16, 24, 32
// * @param srcStride the source number of bytes per line
// * @param srcOrder the source byte ordering: one of MSB_FIRST or LSB_FIRST;
// *        ignored if srcDepth is not 16 or 32
// * @param srcX the top-left x-coord of the source blit region
// * @param srcY the top-left y-coord of the source blit region
// * @param srcWidth the width of the source blit region
// * @param srcHeight the height of the source blit region
// * @param srcRedMask the source red channel mask
// * @param srcGreenMask the source green channel mask
// * @param srcBlueMask the source blue channel mask
// * @param alphaMode the alpha blending or mask mode, may be
// *        an integer 0-255 for global alpha; ignored if BLIT_ALPHA
// *        not specified in the blitter operations
// *        (see ALPHA_MODE_xxx constants)
// * @param alphaData the alpha blending or mask data, varies depending
// *        on the value of alphaMode and sometimes ignored
// * @param alphaStride the alpha data number of bytes per line
// * @param alphaX the top-left x-coord of the alpha blit region
// * @param alphaY the top-left y-coord of the alpha blit region
// * @param destData the destination byte array containing image data
// * @param destDepth the destination depth: one of 8, 16, 24, 32
// * @param destStride the destination number of bytes per line
// * @param destOrder the destination byte ordering: one of MSB_FIRST or LSB_FIRST;
// *        ignored if destDepth is not 16 or 32
// * @param destX the top-left x-coord of the destination blit region
// * @param destY the top-left y-coord of the destination blit region
// * @param destWidth the width of the destination blit region
// * @param destHeight the height of the destination blit region
// * @param destRedMask the destination red channel mask
// * @param destGreenMask the destination green channel mask
// * @param destBlueMask the destination blue channel mask
// * @param flipX if true the resulting image is flipped along the vertical axis
// * @param flipY if true the resulting image is flipped along the horizontal axis
// */
//static void blit(int op,
//    byte[] srcData, int srcDepth, int srcStride, int srcOrder,
//    int srcX, int srcY, int srcWidth, int srcHeight,
//    int srcRedMask, int srcGreenMask, int srcBlueMask,
//    int alphaMode, byte[] alphaData, int alphaStride, int alphaX, int alphaY,
//    byte[] destData, int destDepth, int destStride, int destOrder,
//    int destX, int destY, int destWidth, int destHeight,
//    int destRedMask, int destGreenMask, int destBlueMask,
//    bool flipX, bool flipY) {
//    if ((destWidth <= 0) || (destHeight <= 0) || (alphaMode == ALPHA_TRANSPARENT)) return;

//    // these should be supplied as params later
//    int srcAlphaMask = 0, destAlphaMask = 0;

//    /*** Prepare scaling data ***/
//    int dwm1 = destWidth - 1;
//    int sfxi = (dwm1 != 0) ? (int)((((long)srcWidth << 16) - 1) / dwm1) : 0;
//    int dhm1 = destHeight - 1;
//    int sfyi = (dhm1 != 0) ? (int)((((long)srcHeight << 16) - 1) / dhm1) : 0;

//    /*** Prepare source-related data ***/
//    int sbpp, stype;
//    switch (srcDepth) {
//        case 8:
//            sbpp = 1;
//            stype = TYPE_GENERIC_8;
//            break;
//        case 16:
//            sbpp = 2;
//            stype = (srcOrder == MSB_FIRST) ? TYPE_GENERIC_16_MSB : TYPE_GENERIC_16_LSB;
//            break;
//        case 24:
//            sbpp = 3;
//            stype = TYPE_GENERIC_24;
//            break;
//        case 32:
//            sbpp = 4;
//            stype = (srcOrder == MSB_FIRST) ? TYPE_GENERIC_32_MSB : TYPE_GENERIC_32_LSB;
//            break;
//        default:
//            //throw new IllegalArgumentException("Invalid source type");
//            return;
//    }			
//    int spr = srcY * srcStride + srcX * sbpp;

//    /*** Prepare destination-related data ***/
//    int dbpp, dtype;
//    switch (destDepth) {
//        case 8:
//            dbpp = 1;
//            dtype = TYPE_GENERIC_8;
//            break;
//        case 16:
//            dbpp = 2;
//            dtype = (destOrder == MSB_FIRST) ? TYPE_GENERIC_16_MSB : TYPE_GENERIC_16_LSB;
//            break;
//        case 24:
//            dbpp = 3;
//            dtype = TYPE_GENERIC_24;
//            break;
//        case 32:
//            dbpp = 4;
//            dtype = (destOrder == MSB_FIRST) ? TYPE_GENERIC_32_MSB : TYPE_GENERIC_32_LSB;
//            break;
//        default:
//            //throw new IllegalArgumentException("Invalid destination type");
//            return;
//    }			
//    int dpr = ((flipY) ? destY + dhm1 : destY) * destStride + ((flipX) ? destX + dwm1 : destX) * dbpp;
//    int dprxi = (flipX) ? -dbpp : dbpp;
//    int dpryi = (flipY) ? -destStride : destStride;

//    /*** Prepare special processing data ***/
//    int apr;
//    if ((op & BLIT_ALPHA) != 0) {
//        switch (alphaMode) {
//            case ALPHA_MASK_UNPACKED:
//            case ALPHA_CHANNEL_SEPARATE:
//                if (alphaData == null) alphaMode = 0x10000;
//                apr = alphaY * alphaStride + alphaX;
//                break;
//            case ALPHA_MASK_PACKED:
//                if (alphaData == null) alphaMode = 0x10000;
//                alphaStride <<= 3;
//                apr = alphaY * alphaStride + alphaX;
//                break;
//            case ALPHA_MASK_INDEX:
//                //throw new IllegalArgumentException("Invalid alpha type");
//                return;
//            case ALPHA_MASK_RGB:
//                if (alphaData == null) alphaMode = 0x10000;
//                apr = 0;
//                break;
//            default:
//                alphaMode = (alphaMode << 16) / 255; // prescale
//            case ALPHA_CHANNEL_SOURCE:
//                apr = 0;
//                break;
//        }
//    } else {
//        alphaMode = 0x10000;
//        apr = 0;
//    }

//    /*** Blit ***/
//    int dp = dpr;
//    int sp = spr;
//    if ((alphaMode == 0x10000) && (stype == dtype) &&
//        (srcRedMask == destRedMask) && (srcGreenMask == destGreenMask) &&
//        (srcBlueMask == destBlueMask) && (srcAlphaMask == destAlphaMask)) {
//        /*** Fast blit (straight copy) ***/
//        switch (sbpp) {
//            case 1:
//                for (int dy = destHeight, sfy = sfyi; dy > 0; --dy, sp = spr += (sfy >> 16) * srcStride, sfy = (sfy & 0xffff) + sfyi, dp = dpr += dpryi) {
//                    for (int dx = destWidth, sfx = sfxi; dx > 0; --dx, dp += dprxi, sfx = (sfx & 0xffff) + sfxi) {
//                        destData[dp] = srcData[sp];
//                        sp += (sfx >> 16);
//                    }
//                }
//                break;					
//            case 2:
//                for (int dy = destHeight, sfy = sfyi; dy > 0; --dy, sp = spr += (sfy >> 16) * srcStride, sfy = (sfy & 0xffff) + sfyi, dp = dpr += dpryi) {
//                    for (int dx = destWidth, sfx = sfxi; dx > 0; --dx, dp += dprxi, sfx = (sfx & 0xffff) + sfxi) {
//                        destData[dp] = srcData[sp];
//                        destData[dp + 1] = srcData[sp + 1];
//                        sp += (sfx >> 16) * 2;
//                    }
//                }
//                break;
//            case 3:
//                for (int dy = destHeight, sfy = sfyi; dy > 0; --dy, sp = spr += (sfy >> 16) * srcStride, sfy = (sfy & 0xffff) + sfyi, dp = dpr += dpryi) {
//                    for (int dx = destWidth, sfx = sfxi; dx > 0; --dx, dp += dprxi, sfx = (sfx & 0xffff) + sfxi) {
//                        destData[dp] = srcData[sp];
//                        destData[dp + 1] = srcData[sp + 1];
//                        destData[dp + 2] = srcData[sp + 2];
//                        sp += (sfx >> 16) * 3;
//                    }
//                }
//                break;
//            case 4:
//                for (int dy = destHeight, sfy = sfyi; dy > 0; --dy, sp = spr += (sfy >> 16) * srcStride, sfy = (sfy & 0xffff) + sfyi, dp = dpr += dpryi) {
//                    for (int dx = destWidth, sfx = sfxi; dx > 0; --dx, dp += dprxi, sfx = (sfx & 0xffff) + sfxi) {
//                        destData[dp] = srcData[sp];
//                        destData[dp + 1] = srcData[sp + 1];
//                        destData[dp + 2] = srcData[sp + 2];
//                        destData[dp + 3] = srcData[sp + 3];
//                        sp += (sfx >> 16) * 4;
//                    }
//                }
//                break;
//        }
//        return;
//    }
//    /*** Comprehensive blit (apply transformations) ***/
//    int srcRedShift = getChannelShift(srcRedMask);
//    byte[] srcReds = ANY_TO_EIGHT[getChannelWidth(srcRedMask, srcRedShift)];
//    int srcGreenShift = getChannelShift(srcGreenMask);
//    byte[] srcGreens = ANY_TO_EIGHT[getChannelWidth(srcGreenMask, srcGreenShift)];
//    int srcBlueShift = getChannelShift(srcBlueMask);
//    byte[] srcBlues = ANY_TO_EIGHT[getChannelWidth(srcBlueMask, srcBlueShift)];
//    int srcAlphaShift = getChannelShift(srcAlphaMask);
//    byte[] srcAlphas = ANY_TO_EIGHT[getChannelWidth(srcAlphaMask, srcAlphaShift)];

//    int destRedShift = getChannelShift(destRedMask);
//    int destRedWidth = getChannelWidth(destRedMask, destRedShift);
//    byte[] destReds = ANY_TO_EIGHT[destRedWidth];
//    int destRedPreShift = 8 - destRedWidth;
//    int destGreenShift = getChannelShift(destGreenMask);
//    int destGreenWidth = getChannelWidth(destGreenMask, destGreenShift);
//    byte[] destGreens = ANY_TO_EIGHT[destGreenWidth];
//    int destGreenPreShift = 8 - destGreenWidth;
//    int destBlueShift = getChannelShift(destBlueMask);
//    int destBlueWidth = getChannelWidth(destBlueMask, destBlueShift);
//    byte[] destBlues = ANY_TO_EIGHT[destBlueWidth];
//    int destBluePreShift = 8 - destBlueWidth;
//    int destAlphaShift = getChannelShift(destAlphaMask);
//    int destAlphaWidth = getChannelWidth(destAlphaMask, destAlphaShift);
//    byte[] destAlphas = ANY_TO_EIGHT[destAlphaWidth];
//    int destAlphaPreShift = 8 - destAlphaWidth;

//    int ap = apr, alpha = alphaMode;
//    int r = 0, g = 0, b = 0, a = 0;
//    int rq = 0, gq = 0, bq = 0, aq = 0;
//    for (int dy = destHeight, sfy = sfyi; dy > 0; --dy,
//            sp = spr += (sfy >> 16) * srcStride,
//            ap = apr += (sfy >> 16) * alphaStride,
//            sfy = (sfy & 0xffff) + sfyi,
//            dp = dpr += dpryi) {
//        for (int dx = destWidth, sfx = sfxi; dx > 0; --dx,
//                dp += dprxi,
//                sfx = (sfx & 0xffff) + sfxi) {
//            /*** READ NEXT PIXEL ***/
//            switch (stype) {
//                case TYPE_GENERIC_8: {
//                    int data = srcData[sp] & 0xff;
//                    sp += (sfx >> 16);
//                    r = srcReds[(data & srcRedMask) >> srcRedShift] & 0xff;
//                    g = srcGreens[(data & srcGreenMask) >> srcGreenShift] & 0xff;
//                    b = srcBlues[(data & srcBlueMask) >> srcBlueShift] & 0xff;
//                    a = srcAlphas[(data & srcAlphaMask) >> srcAlphaShift] & 0xff;
//                } break;
//                case TYPE_GENERIC_16_MSB: {
//                    int data = ((srcData[sp] & 0xff) << 8) | (srcData[sp + 1] & 0xff);
//                    sp += (sfx >> 16) * 2;
//                    r = srcReds[(data & srcRedMask) >> srcRedShift] & 0xff;
//                    g = srcGreens[(data & srcGreenMask) >> srcGreenShift] & 0xff;
//                    b = srcBlues[(data & srcBlueMask) >> srcBlueShift] & 0xff;
//                    a = srcAlphas[(data & srcAlphaMask) >> srcAlphaShift] & 0xff;
//                } break;
//                case TYPE_GENERIC_16_LSB: {
//                    int data = ((srcData[sp + 1] & 0xff) << 8) | (srcData[sp] & 0xff);
//                    sp += (sfx >> 16) * 2;
//                    r = srcReds[(data & srcRedMask) >> srcRedShift] & 0xff;
//                    g = srcGreens[(data & srcGreenMask) >> srcGreenShift] & 0xff;
//                    b = srcBlues[(data & srcBlueMask) >> srcBlueShift] & 0xff;
//                    a = srcAlphas[(data & srcAlphaMask) >> srcAlphaShift] & 0xff;
//                } break;
//                case TYPE_GENERIC_24: {
//                    int data = (( ((srcData[sp] & 0xff) << 8) |
//                        (srcData[sp + 1] & 0xff)) << 8) |
//                        (srcData[sp + 2] & 0xff);
//                    sp += (sfx >> 16) * 3;
//                    r = srcReds[(data & srcRedMask) >> srcRedShift] & 0xff;
//                    g = srcGreens[(data & srcGreenMask) >> srcGreenShift] & 0xff;
//                    b = srcBlues[(data & srcBlueMask) >> srcBlueShift] & 0xff;
//                    a = srcAlphas[(data & srcAlphaMask) >> srcAlphaShift] & 0xff;
//                } break;
//                case TYPE_GENERIC_32_MSB: {
//                    int data = (( (( ((srcData[sp] & 0xff) << 8) |
//                        (srcData[sp + 1] & 0xff)) << 8) |
//                        (srcData[sp + 2] & 0xff)) << 8) |
//                        (srcData[sp + 3] & 0xff);
//                    sp += (sfx >> 16) * 4;
//                    r = srcReds[(data & srcRedMask) >> srcRedShift] & 0xff;
//                    g = srcGreens[(data & srcGreenMask) >> srcGreenShift] & 0xff;
//                    b = srcBlues[(data & srcBlueMask) >> srcBlueShift] & 0xff;
//                    a = srcAlphas[(data & srcAlphaMask) >> srcAlphaShift] & 0xff;
//                } break;
//                case TYPE_GENERIC_32_LSB: {
//                    int data = (( (( ((srcData[sp + 3] & 0xff) << 8) |
//                        (srcData[sp + 2] & 0xff)) << 8) |
//                        (srcData[sp + 1] & 0xff)) << 8) |
//                        (srcData[sp] & 0xff);
//                    sp += (sfx >> 16) * 4;
//                    r = srcReds[(data & srcRedMask) >> srcRedShift] & 0xff;
//                    g = srcGreens[(data & srcGreenMask) >> srcGreenShift] & 0xff;
//                    b = srcBlues[(data & srcBlueMask) >> srcBlueShift] & 0xff;
//                    a = srcAlphas[(data & srcAlphaMask) >> srcAlphaShift] & 0xff;
//                } break;
//            }

//            /*** DO SPECIAL PROCESSING IF REQUIRED ***/
//            switch (alphaMode) {
//                case ALPHA_CHANNEL_SEPARATE:
//                    alpha = ((alphaData[ap] & 0xff) << 16) / 255;
//                    ap += (sfx >> 16);
//                    break;
//                case ALPHA_CHANNEL_SOURCE:
//                    alpha = (a << 16) / 255;
//                    break;
//                case ALPHA_MASK_UNPACKED:
//                    alpha = (alphaData[ap] != 0) ? 0x10000 : 0;
//                    ap += (sfx >> 16);
//                    break;						
//                case ALPHA_MASK_PACKED:
//                    alpha = (alphaData[ap >> 3] << ((ap & 7) + 9)) & 0x10000;
//                    ap += (sfx >> 16);
//                    break;
//                case ALPHA_MASK_RGB:
//                    alpha = 0x10000;
//                    for (int i = 0; i < alphaData.Length; i += 3) {
//                        if ((r == alphaData[i]) && (g == alphaData[i + 1]) && (b == alphaData[i + 2])) {
//                            alpha = 0x0000;
//                            break;
//                        }
//                    }
//                    break;
//            }
//            if (alpha != 0x10000) {
//                if (alpha == 0x0000) continue;
//                switch (dtype) {
//                    case TYPE_GENERIC_8: {
//                        int data = destData[dp] & 0xff;
//                        rq = destReds[(data & destRedMask) >> destRedShift] & 0xff;
//                        gq = destGreens[(data & destGreenMask) >> destGreenShift] & 0xff;
//                        bq = destBlues[(data & destBlueMask) >> destBlueShift] & 0xff;
//                        aq = destAlphas[(data & destAlphaMask) >> destAlphaShift] & 0xff;
//                    } break;
//                    case TYPE_GENERIC_16_MSB: {
//                        int data = ((destData[dp] & 0xff) << 8) | (destData[dp + 1] & 0xff);
//                        rq = destReds[(data & destRedMask) >> destRedShift] & 0xff;
//                        gq = destGreens[(data & destGreenMask) >> destGreenShift] & 0xff;
//                        bq = destBlues[(data & destBlueMask) >> destBlueShift] & 0xff;
//                        aq = destAlphas[(data & destAlphaMask) >> destAlphaShift] & 0xff;
//                    } break;
//                    case TYPE_GENERIC_16_LSB: {
//                        int data = ((destData[dp + 1] & 0xff) << 8) | (destData[dp] & 0xff);
//                        rq = destReds[(data & destRedMask) >> destRedShift] & 0xff;
//                        gq = destGreens[(data & destGreenMask) >> destGreenShift] & 0xff;
//                        bq = destBlues[(data & destBlueMask) >> destBlueShift] & 0xff;
//                        aq = destAlphas[(data & destAlphaMask) >> destAlphaShift] & 0xff;
//                    } break;
//                    case TYPE_GENERIC_24: {
//                        int data = (( ((destData[dp] & 0xff) << 8) |
//                            (destData[dp + 1] & 0xff)) << 8) |
//                            (destData[dp + 2] & 0xff);
//                        rq = destReds[(data & destRedMask) >> destRedShift] & 0xff;
//                        gq = destGreens[(data & destGreenMask) >> destGreenShift] & 0xff;
//                        bq = destBlues[(data & destBlueMask) >> destBlueShift] & 0xff;
//                        aq = destAlphas[(data & destAlphaMask) >> destAlphaShift] & 0xff;
//                    } break;
//                    case TYPE_GENERIC_32_MSB: {
//                        int data = (( (( ((destData[dp] & 0xff) << 8) |
//                            (destData[dp + 1] & 0xff)) << 8) |
//                            (destData[dp + 2] & 0xff)) << 8) |
//                            (destData[dp + 3] & 0xff);
//                        rq = destReds[(data & destRedMask) >> destRedShift] & 0xff;
//                        gq = destGreens[(data & destGreenMask) >> destGreenShift] & 0xff;
//                        bq = destBlues[(data & destBlueMask) >> destBlueShift] & 0xff;
//                        aq = destAlphas[(data & destAlphaMask) >> destAlphaShift] & 0xff;
//                    } break;
//                    case TYPE_GENERIC_32_LSB: {
//                        int data = (( (( ((destData[dp + 3] & 0xff) << 8) |
//                            (destData[dp + 2] & 0xff)) << 8) |
//                            (destData[dp + 1] & 0xff)) << 8) |
//                            (destData[dp] & 0xff);
//                        rq = destReds[(data & destRedMask) >> destRedShift] & 0xff;
//                        gq = destGreens[(data & destGreenMask) >> destGreenShift] & 0xff;
//                        bq = destBlues[(data & destBlueMask) >> destBlueShift] & 0xff;
//                        aq = destAlphas[(data & destAlphaMask) >> destAlphaShift] & 0xff;
//                    } break;
//                }
//                // Perform alpha blending
//                a = aq + ((a - aq) * alpha >> 16);
//                r = rq + ((r - rq) * alpha >> 16);
//                g = gq + ((g - gq) * alpha >> 16);
//                b = bq + ((b - bq) * alpha >> 16);
//            }

//            /*** WRITE NEXT PIXEL ***/
//            int data = 
//                (r >> destRedPreShift << destRedShift) |
//                (g >> destGreenPreShift << destGreenShift) |
//                (b >> destBluePreShift << destBlueShift) |
//                (a >> destAlphaPreShift << destAlphaShift);
//            switch (dtype) {
//                case TYPE_GENERIC_8: {
//                    destData[dp] = (byte) data;
//                } break;
//                case TYPE_GENERIC_16_MSB: {
//                    destData[dp] = (byte) (data >> 8);
//                    destData[dp + 1] = (byte) (data & 0xff);
//                } break;
//                case TYPE_GENERIC_16_LSB: {
//                    destData[dp] = (byte) (data & 0xff);
//                    destData[dp + 1] = (byte) (data >> 8);
//                } break;
//                case TYPE_GENERIC_24: {
//                    destData[dp] = (byte) (data >> 16);
//                    destData[dp + 1] = (byte) (data >> 8);
//                    destData[dp + 2] = (byte) (data & 0xff);
//                } break;
//                case TYPE_GENERIC_32_MSB: {
//                    destData[dp] = (byte) (data >> 24);
//                    destData[dp + 1] = (byte) (data >> 16);
//                    destData[dp + 2] = (byte) (data >> 8);
//                    destData[dp + 3] = (byte) (data & 0xff);
//                } break;
//                case TYPE_GENERIC_32_LSB: {
//                    destData[dp] = (byte) (data & 0xff);
//                    destData[dp + 1] = (byte) (data >> 8);
//                    destData[dp + 2] = (byte) (data >> 16);
//                    destData[dp + 3] = (byte) (data >> 24);
//                } break;
//            }
//        }
//    }			
//}

///**
// * Blits an index palette image into an index palette image.
// * <p>
// * Note: The source and destination red, green, and blue
// * arrays may be null if no alpha blending or dither is to be
// * performed.
// * </p>
// * 
// * @param op the blitter operation: a combination of BLIT_xxx flags
// *        (see BLIT_xxx constants)
// * @param srcData the source byte array containing image data
// * @param srcDepth the source depth: one of 1, 2, 4, 8
// * @param srcStride the source number of bytes per line
// * @param srcOrder the source byte ordering: one of MSB_FIRST or LSB_FIRST;
// *        ignored if srcDepth is not 1
// * @param srcX the top-left x-coord of the source blit region
// * @param srcY the top-left y-coord of the source blit region
// * @param srcWidth the width of the source blit region
// * @param srcHeight the height of the source blit region
// * @param srcReds the source palette red component intensities
// * @param srcGreens the source palette green component intensities
// * @param srcBlues the source palette blue component intensities
// * @param alphaMode the alpha blending or mask mode, may be
// *        an integer 0-255 for global alpha; ignored if BLIT_ALPHA
// *        not specified in the blitter operations
// *        (see ALPHA_MODE_xxx constants)
// * @param alphaData the alpha blending or mask data, varies depending
// *        on the value of alphaMode and sometimes ignored
// * @param alphaStride the alpha data number of bytes per line
// * @param alphaX the top-left x-coord of the alpha blit region
// * @param alphaY the top-left y-coord of the alpha blit region
// * @param destData the destination byte array containing image data
// * @param destDepth the destination depth: one of 1, 2, 4, 8
// * @param destStride the destination number of bytes per line
// * @param destOrder the destination byte ordering: one of MSB_FIRST or LSB_FIRST;
// *        ignored if destDepth is not 1
// * @param destX the top-left x-coord of the destination blit region
// * @param destY the top-left y-coord of the destination blit region
// * @param destWidth the width of the destination blit region
// * @param destHeight the height of the destination blit region
// * @param destReds the destination palette red component intensities
// * @param destGreens the destination palette green component intensities
// * @param destBlues the destination palette blue component intensities
// * @param flipX if true the resulting image is flipped along the vertical axis
// * @param flipY if true the resulting image is flipped along the horizontal axis
// */
//static void blit(int op,
//    byte[] srcData, int srcDepth, int srcStride, int srcOrder,
//    int srcX, int srcY, int srcWidth, int srcHeight,
//    byte[] srcReds, byte[] srcGreens, byte[] srcBlues,
//    int alphaMode, byte[] alphaData, int alphaStride, int alphaX, int alphaY,
//    byte[] destData, int destDepth, int destStride, int destOrder,
//    int destX, int destY, int destWidth, int destHeight,
//    byte[] destReds, byte[] destGreens, byte[] destBlues,
//    bool flipX, bool flipY) {
//    if ((destWidth <= 0) || (destHeight <= 0) || (alphaMode == ALPHA_TRANSPARENT)) return;

//    /*** Prepare scaling data ***/
//    int dwm1 = destWidth - 1;
//    int sfxi = (dwm1 != 0) ? (int)((((long)srcWidth << 16) - 1) / dwm1) : 0;
//    int dhm1 = destHeight - 1;
//    int sfyi = (dhm1 != 0) ? (int)((((long)srcHeight << 16) - 1) / dhm1) : 0;

//    /*** Prepare source-related data ***/
//    int stype;
//    switch (srcDepth) {
//        case 8:
//            stype = TYPE_INDEX_8;
//            break;
//        case 4:
//            srcStride <<= 1;
//            stype = TYPE_INDEX_4;
//            break;
//        case 2:
//            srcStride <<= 2;
//            stype = TYPE_INDEX_2;
//            break;
//        case 1:
//            srcStride <<= 3;
//            stype = (srcOrder == MSB_FIRST) ? TYPE_INDEX_1_MSB : TYPE_INDEX_1_LSB;
//            break;
//        default:
//            //throw new IllegalArgumentException("Invalid source type");
//            return;		
//    }			
//    int spr = srcY * srcStride + srcX;

//    /*** Prepare destination-related data ***/
//    int dtype;
//    switch (destDepth) {
//        case 8:
//            dtype = TYPE_INDEX_8;
//            break;
//        case 4:
//            destStride <<= 1;
//            dtype = TYPE_INDEX_4;
//            break;
//        case 2:
//            destStride <<= 2;
//            dtype = TYPE_INDEX_2;
//            break;
//        case 1:
//            destStride <<= 3;
//            dtype = (destOrder == MSB_FIRST) ? TYPE_INDEX_1_MSB : TYPE_INDEX_1_LSB;
//            break;
//        default:
//            //throw new IllegalArgumentException("Invalid source type");
//            return;
//    }			
//    int dpr = ((flipY) ? destY + dhm1 : destY) * destStride + ((flipX) ? destX + dwm1 : destX);
//    int dprxi = (flipX) ? -1 : 1;
//    int dpryi = (flipY) ? -destStride : destStride;

//    /*** Prepare special processing data ***/
//    int apr;
//    if ((op & BLIT_ALPHA) != 0) {
//        switch (alphaMode) {
//            case ALPHA_MASK_UNPACKED:
//            case ALPHA_CHANNEL_SEPARATE:
//                if (alphaData == null) alphaMode = 0x10000;
//                apr = alphaY * alphaStride + alphaX;
//                break;
//            case ALPHA_MASK_PACKED:
//                if (alphaData == null) alphaMode = 0x10000;
//                alphaStride <<= 3;
//                apr = alphaY * alphaStride + alphaX;
//                break;
//            case ALPHA_MASK_INDEX:
//            case ALPHA_MASK_RGB:
//                if (alphaData == null) alphaMode = 0x10000;
//                apr = 0;
//                break;
//            default:
//                alphaMode = (alphaMode << 16) / 255; // prescale
//            case ALPHA_CHANNEL_SOURCE:
//                apr = 0;
//                break;
//        }
//    } else {
//        alphaMode = 0x10000;
//        apr = 0;
//    }
//    bool ditherEnabled = (op & BLIT_DITHER) != 0;

//    /*** Blit ***/
//    int dp = dpr;
//    int sp = spr;
//    int ap = apr;
//    int destPaletteSize = 1 << destDepth;
//    if ((destReds != null) && (destReds.Length < destPaletteSize)) destPaletteSize = destReds.Length;
//    byte[] paletteMapping = null;
//    bool isExactPaletteMapping = true;
//    switch (alphaMode) {
//        case 0x10000:
//            /*** If the palettes and formats are equivalent use a one-to-one mapping ***/
//            if ((stype == dtype) &&
//                (srcReds == destReds) && (srcGreens == destGreens) && (srcBlues == destBlues)) {
//                paletteMapping = ONE_TO_ONE_MAPPING;
//                break;
//            /*** If palettes have not been supplied, supply a suitable mapping ***/
//            } else if ((srcReds == null) || (destReds == null)) {
//                if (srcDepth <= destDepth) {
//                    paletteMapping = ONE_TO_ONE_MAPPING;
//                } else {
//                    paletteMapping = new byte[1 << srcDepth];
//                    int mask = (0xff << destDepth) >> 8;
//                    for (int i = 0; i < paletteMapping.Length; ++i) paletteMapping[i] = (byte)(i & mask);
//                }
//                break;
//            }
//        case ALPHA_MASK_UNPACKED:
//        case ALPHA_MASK_PACKED:
//        case ALPHA_MASK_INDEX:
//        case ALPHA_MASK_RGB:
//            /*** Generate a palette mapping ***/
//            int srcPaletteSize = 1 << srcDepth;
//            paletteMapping = new byte[srcPaletteSize];
//            if ((srcReds != null) && (srcReds.Length < srcPaletteSize)) srcPaletteSize = srcReds.Length;
//            for (int i = 0, r, g, b, index; i < srcPaletteSize; ++i) {
//                r = srcReds[i] & 0xff;
//                g = srcGreens[i] & 0xff;
//                b = srcBlues[i] & 0xff;
//                index = 0;
//                int minDistance = 0x7fffffff;
//                for (int j = 0, dr, dg, db, distance; j < destPaletteSize; ++j) {
//                    dr = (destReds[j] & 0xff) - r;
//                    dg = (destGreens[j] & 0xff) - g;
//                    db = (destBlues[j] & 0xff) - b;
//                    distance = dr * dr + dg * dg + db * db;
//                    if (distance < minDistance) {
//                        index = j;
//                        if (distance == 0) break;
//                        minDistance = distance;
//                    }
//                }
//                paletteMapping[i] = (byte)index;
//                if (minDistance != 0) isExactPaletteMapping = false;
//            }
//            break;
//    }
//    if ((paletteMapping != null) && (isExactPaletteMapping || ! ditherEnabled)) {
//        if ((stype == dtype) && (alphaMode == 0x10000)) {
//            /*** Fast blit (copy w/ mapping) ***/
//            switch (stype) {
//                case TYPE_INDEX_8:
//                    for (int dy = destHeight, sfy = sfyi; dy > 0; --dy, sp = spr += (sfy >> 16) * srcStride, sfy = (sfy & 0xffff) + sfyi, dp = dpr += dpryi) {
//                        for (int dx = destWidth, sfx = sfxi; dx > 0; --dx, dp += dprxi, sfx = (sfx & 0xffff) + sfxi) {
//                            destData[dp] = paletteMapping[srcData[sp] & 0xff];
//                            sp += (sfx >> 16);
//                        }
//                    }
//                    break;					
//                case TYPE_INDEX_4:
//                    for (int dy = destHeight, sfy = sfyi; dy > 0; --dy, sp = spr += (sfy >> 16) * srcStride, sfy = (sfy & 0xffff) + sfyi, dp = dpr += dpryi) {
//                        for (int dx = destWidth, sfx = sfxi; dx > 0; --dx, dp += dprxi, sfx = (sfx & 0xffff) + sfxi) {
//                            int v;
//                            if ((sp & 1) != 0) v = paletteMapping[srcData[sp >> 1] & 0x0f];
//                            else v = (srcData[sp >> 1] >> 4) & 0x0f;
//                            sp += (sfx >> 16);
//                            if ((dp & 1) != 0) destData[dp >> 1] = (byte)((destData[dp >> 1] & 0xf0) | v);
//                            else destData[dp >> 1] = (byte)((destData[dp >> 1] & 0x0f) | (v << 4));
//                        }
//                    }
//                    break;
//                case TYPE_INDEX_2:
//                    for (int dy = destHeight, sfy = sfyi; dy > 0; --dy, sp = spr += (sfy >> 16) * srcStride, sfy = (sfy & 0xffff) + sfyi, dp = dpr += dpryi) {
//                        for (int dx = destWidth, sfx = sfxi; dx > 0; --dx, dp += dprxi, sfx = (sfx & 0xffff) + sfxi) {
//                            int index = paletteMapping[(srcData[sp >> 2] >> (6 - (sp & 3) * 2)) & 0x03];
//                            sp += (sfx >> 16);
//                            int shift = 6 - (dp & 3) * 2;
//                            destData[dp >> 2] = (byte)(destData[dp >> 2] & ~(0x03 << shift) | (index << shift));
//                        }
//                    }
//                    break;					
//                case TYPE_INDEX_1_MSB:
//                    for (int dy = destHeight, sfy = sfyi; dy > 0; --dy, sp = spr += (sfy >> 16) * srcStride, sfy = (sfy & 0xffff) + sfyi, dp = dpr += dpryi) {
//                        for (int dx = destWidth, sfx = sfxi; dx > 0; --dx, dp += dprxi, sfx = (sfx & 0xffff) + sfxi) {
//                            int index = paletteMapping[(srcData[sp >> 3] >> (7 - (sp & 7))) & 0x01];
//                            sp += (sfx >> 16);
//                            int shift = 7 - (dp & 7);
//                            destData[dp >> 3] = (byte)(destData[dp >> 3] & ~(0x01 << shift) | (index << shift));
//                        }
//                    }
//                    break;					
//                case TYPE_INDEX_1_LSB:
//                    for (int dy = destHeight, sfy = sfyi; dy > 0; --dy, sp = spr += (sfy >> 16) * srcStride, sfy = (sfy & 0xffff) + sfyi, dp = dpr += dpryi) {
//                        for (int dx = destWidth, sfx = sfxi; dx > 0; --dx, dp += dprxi, sfx = (sfx & 0xffff) + sfxi) {
//                            int index = paletteMapping[(srcData[sp >> 3] >> (sp & 7)) & 0x01];
//                            sp += (sfx >> 16);
//                            int shift = dp & 7;
//                            destData[dp >> 3] = (byte)(destData[dp >> 3] & ~(0x01 << shift) | (index << shift));
//                        }
//                    }
//                    break;
//            }
//        } else {
//            /*** Convert between indexed modes using mapping and mask ***/
//            for (int dy = destHeight, sfy = sfyi; dy > 0; --dy,
//                    sp = spr += (sfy >> 16) * srcStride,
//                    sfy = (sfy & 0xffff) + sfyi,
//                    dp = dpr += dpryi) {
//                for (int dx = destWidth, sfx = sfxi; dx > 0; --dx,
//                        dp += dprxi,
//                        sfx = (sfx & 0xffff) + sfxi) {
//                    int index;
//                    /*** READ NEXT PIXEL ***/
//                    switch (stype) {
//                        case TYPE_INDEX_8:
//                            index = srcData[sp] & 0xff;
//                            sp += (sfx >> 16);
//                            break;					
//                        case TYPE_INDEX_4:
//                            if ((sp & 1) != 0) index = srcData[sp >> 1] & 0x0f;
//                            else index = (srcData[sp >> 1] >> 4) & 0x0f;
//                            sp += (sfx >> 16);
//                            break;					
//                        case TYPE_INDEX_2:
//                            index = (srcData[sp >> 2] >> (6 - (sp & 3) * 2)) & 0x03;
//                            sp += (sfx >> 16);
//                            break;					
//                        case TYPE_INDEX_1_MSB:
//                            index = (srcData[sp >> 3] >> (7 - (sp & 7))) & 0x01;
//                            sp += (sfx >> 16);
//                            break;					
//                        case TYPE_INDEX_1_LSB:
//                            index = (srcData[sp >> 3] >> (sp & 7)) & 0x01;
//                            sp += (sfx >> 16);
//                            break;
//                        default:
//                            return;
//                    }
//                    /*** APPLY MASK ***/
//                    switch (alphaMode) {
//                        case ALPHA_MASK_UNPACKED: {
//                            byte mask = alphaData[ap];
//                            ap += (sfx >> 16);
//                            if (mask == 0) continue;
//                        } break;
//                        case ALPHA_MASK_PACKED: {
//                            int mask = alphaData[ap >> 3] & (1 << (ap & 7));
//                            ap += (sfx >> 16);
//                            if (mask == 0) continue;
//                        } break;
//                        case ALPHA_MASK_INDEX: {
//                            int i = 0;
//                            while (i < alphaData.Length) {
//                                if (index == (alphaData[i] & 0xff)) break;
//                            }
//                            if (i < alphaData.Length) continue;
//                        } break;
//                        case ALPHA_MASK_RGB: {
//                            byte r = srcReds[index], g = srcGreens[index], b = srcBlues[index];
//                            int i = 0;
//                            while (i < alphaData.Length) {
//                                if ((r == alphaData[i]) && (g == alphaData[i + 1]) && (b == alphaData[i + 2])) break;
//                                i += 3;
//                            }
//                            if (i < alphaData.Length) continue;
//                        } break;
//                    }
//                    index = paletteMapping[index] & 0xff;
			
//                    /*** WRITE NEXT PIXEL ***/
//                    switch (dtype) {
//                        case TYPE_INDEX_8:
//                            destData[dp] = (byte) index;
//                            break;
//                        case TYPE_INDEX_4:
//                            if ((dp & 1) != 0) destData[dp >> 1] = (byte)((destData[dp >> 1] & 0xf0) | index);
//                            else destData[dp >> 1] = (byte)((destData[dp >> 1] & 0x0f) | (index << 4));
//                            break;					
//                        case TYPE_INDEX_2: {
//                            int shift = 6 - (dp & 3) * 2;
//                            destData[dp >> 2] = (byte)(destData[dp >> 2] & ~(0x03 << shift) | (index << shift));
//                        } break;					
//                        case TYPE_INDEX_1_MSB: {
//                            int shift = 7 - (dp & 7);
//                            destData[dp >> 3] = (byte)(destData[dp >> 3] & ~(0x01 << shift) | (index << shift));
//                        } break;
//                        case TYPE_INDEX_1_LSB: {
//                            int shift = dp & 7;
//                            destData[dp >> 3] = (byte)(destData[dp >> 3] & ~(0x01 << shift) | (index << shift));
//                        } break;					
//                    }
//                }
//            }
//        }
//        return;
//    }
		
//    /*** Comprehensive blit (apply transformations) ***/
//    int alpha = alphaMode;
//    int index = 0;
//    int indexq = 0;
//    int lastindex = 0, lastr = -1, lastg = -1, lastb = -1;
//    int[] rerr, gerr, berr;
//    if (ditherEnabled) {
//        rerr = new int[destWidth + 2];
//        gerr = new int[destWidth + 2];
//        berr = new int[destWidth + 2];
//    } else {
//        rerr = null; gerr = null; berr = null;
//    }
//    for (int dy = destHeight, sfy = sfyi; dy > 0; --dy,
//            sp = spr += (sfy >> 16) * srcStride,
//            ap = apr += (sfy >> 16) * alphaStride,
//            sfy = (sfy & 0xffff) + sfyi,
//            dp = dpr += dpryi) {
//        int lrerr = 0, lgerr = 0, lberr = 0;
//        for (int dx = destWidth, sfx = sfxi; dx > 0; --dx,
//                dp += dprxi,
//                sfx = (sfx & 0xffff) + sfxi) {
//            /*** READ NEXT PIXEL ***/
//            switch (stype) {
//                case TYPE_INDEX_8:
//                    index = srcData[sp] & 0xff;
//                    sp += (sfx >> 16);
//                    break;
//                case TYPE_INDEX_4:
//                    if ((sp & 1) != 0) index = srcData[sp >> 1] & 0x0f;
//                    else index = (srcData[sp >> 1] >> 4) & 0x0f;
//                    sp += (sfx >> 16);
//                    break;
//                case TYPE_INDEX_2:
//                    index = (srcData[sp >> 2] >> (6 - (sp & 3) * 2)) & 0x03;
//                    sp += (sfx >> 16);
//                    break;
//                case TYPE_INDEX_1_MSB:
//                    index = (srcData[sp >> 3] >> (7 - (sp & 7))) & 0x01;
//                    sp += (sfx >> 16);
//                    break;
//                case TYPE_INDEX_1_LSB:
//                    index = (srcData[sp >> 3] >> (sp & 7)) & 0x01;
//                    sp += (sfx >> 16);
//                    break;
//            }

//            /*** DO SPECIAL PROCESSING IF REQUIRED ***/
//            int r = srcReds[index] & 0xff, g = srcGreens[index] & 0xff, b = srcBlues[index] & 0xff;
//            switch (alphaMode) {
//                case ALPHA_CHANNEL_SEPARATE:
//                    alpha = ((alphaData[ap] & 0xff) << 16) / 255;
//                    ap += (sfx >> 16);
//                    break;
//                case ALPHA_MASK_UNPACKED:
//                    alpha = (alphaData[ap] != 0) ? 0x10000 : 0;
//                    ap += (sfx >> 16);
//                    break;						
//                case ALPHA_MASK_PACKED:
//                    alpha = (alphaData[ap >> 3] << ((ap & 7) + 9)) & 0x10000;
//                    ap += (sfx >> 16);
//                    break;
//                case ALPHA_MASK_INDEX: { // could speed up using binary search if we sorted the indices
//                    int i = 0;
//                    while (i < alphaData.Length) {
//                        if (index == (alphaData[i] & 0xff)) break;
//                    }
//                    if (i < alphaData.Length) continue;
//                } break;
//                case ALPHA_MASK_RGB: {
//                    int i = 0;
//                    while (i < alphaData.Length) {
//                        if ((r == (alphaData[i] & 0xff)) &&
//                            (g == (alphaData[i + 1] & 0xff)) &&
//                            (b == (alphaData[i + 2] & 0xff))) break;
//                        i += 3;
//                    }
//                    if (i < alphaData.Length) continue;
//                } break;
//            }
//            if (alpha != 0x10000) {
//                if (alpha == 0x0000) continue;
//                switch (dtype) {
//                    case TYPE_INDEX_8:
//                        indexq = destData[dp] & 0xff;
//                        break;
//                    case TYPE_INDEX_4:
//                        if ((dp & 1) != 0) indexq = destData[dp >> 1] & 0x0f;
//                        else indexq = (destData[dp >> 1] >> 4) & 0x0f;
//                        break;
//                    case TYPE_INDEX_2:
//                        indexq = (destData[dp >> 2] >> (6 - (dp & 3) * 2)) & 0x03;
//                        break;
//                    case TYPE_INDEX_1_MSB:
//                        indexq = (destData[dp >> 3] >> (7 - (dp & 7))) & 0x01;
//                        break;
//                    case TYPE_INDEX_1_LSB:
//                        indexq = (destData[dp >> 3] >> (dp & 7)) & 0x01;
//                        break;
//                }
//                // Perform alpha blending
//                int rq = destReds[indexq] & 0xff;
//                int gq = destGreens[indexq] & 0xff;
//                int bq = destBlues[indexq] & 0xff;
//                r = rq + ((r - rq) * alpha >> 16);
//                g = gq + ((g - gq) * alpha >> 16);
//                b = bq + ((b - bq) * alpha >> 16);
//            }

//            /*** MAP COLOR TO THE PALETTE ***/
//            if (ditherEnabled) {
//                // Floyd-Steinberg error diffusion
//                r += rerr[dx] >> 4;
//                if (r < 0) r = 0; else if (r > 255) r = 255;
//                g += gerr[dx] >> 4;
//                if (g < 0) g = 0; else if (g > 255) g = 255;
//                b += berr[dx] >> 4;
//                if (b < 0) b = 0; else if (b > 255) b = 255;
//                rerr[dx] = lrerr;
//                gerr[dx] = lgerr;
//                berr[dx] = lberr;
//            }
//            if (r != lastr || g != lastg || b != lastb) {
//                // moving the variable declarations out seems to make the JDK JIT happier...
//                for (int j = 0, dr, dg, db, distance, minDistance = 0x7fffffff; j < destPaletteSize; ++j) {
//                    dr = (destReds[j] & 0xff) - r;
//                    dg = (destGreens[j] & 0xff) - g;
//                    db = (destBlues[j] & 0xff) - b;
//                    distance = dr * dr + dg * dg + db * db;
//                    if (distance < minDistance) {
//                        lastindex = j;
//                        if (distance == 0) break;
//                        minDistance = distance;
//                    }
//                }
//                lastr = r; lastg = g; lastb = b;
//            }
//            if (ditherEnabled) {
//                // Floyd-Steinberg error diffusion, cont'd...
//                int dxm1 = dx - 1, dxp1 = dx + 1;
//                int acc;
//                rerr[dxp1] += acc = (lrerr = r - (destReds[lastindex] & 0xff)) + lrerr + lrerr;
//                rerr[dx] += acc += lrerr + lrerr;
//                rerr[dxm1] += acc + lrerr + lrerr;
//                gerr[dxp1] += acc = (lgerr = g - (destGreens[lastindex] & 0xff)) + lgerr + lgerr;
//                gerr[dx] += acc += lgerr + lgerr;
//                gerr[dxm1] += acc + lgerr + lgerr;
//                berr[dxp1] += acc = (lberr = b - (destBlues[lastindex] & 0xff)) + lberr + lberr;
//                berr[dx] += acc += lberr + lberr;
//                berr[dxm1] += acc + lberr + lberr;
//            }

//            /*** WRITE NEXT PIXEL ***/
//            switch (dtype) {
//                case TYPE_INDEX_8:
//                    destData[dp] = (byte) lastindex;
//                    break;
//                case TYPE_INDEX_4:
//                    if ((dp & 1) != 0) destData[dp >> 1] = (byte)((destData[dp >> 1] & 0xf0) | lastindex);
//                    else destData[dp >> 1] = (byte)((destData[dp >> 1] & 0x0f) | (lastindex << 4));
//                    break;
//                case TYPE_INDEX_2: {
//                    int shift = 6 - (dp & 3) * 2;
//                    destData[dp >> 2] = (byte)(destData[dp >> 2] & ~(0x03 << shift) | (lastindex << shift));
//                } break;					
//                case TYPE_INDEX_1_MSB: {
//                    int shift = 7 - (dp & 7);
//                    destData[dp >> 3] = (byte)(destData[dp >> 3] & ~(0x01 << shift) | (lastindex << shift));
//                } break;
//                case TYPE_INDEX_1_LSB: {
//                    int shift = dp & 7;
//                    destData[dp >> 3] = (byte)(destData[dp >> 3] & ~(0x01 << shift) | (lastindex << shift));
//                } break;					
//            }
//        }
//    }
//}

///**
// * Blits an index palette image into a direct palette image.
// * <p>
// * Note: The source and destination masks and palettes must
// * always be fully specified.
// * </p>
// * 
// * @param op the blitter operation: a combination of BLIT_xxx flags
// *        (see BLIT_xxx constants)
// * @param srcData the source byte array containing image data
// * @param srcDepth the source depth: one of 1, 2, 4, 8
// * @param srcStride the source number of bytes per line
// * @param srcOrder the source byte ordering: one of MSB_FIRST or LSB_FIRST;
// *        ignored if srcDepth is not 1
// * @param srcX the top-left x-coord of the source blit region
// * @param srcY the top-left y-coord of the source blit region
// * @param srcWidth the width of the source blit region
// * @param srcHeight the height of the source blit region
// * @param srcReds the source palette red component intensities
// * @param srcGreens the source palette green component intensities
// * @param srcBlues the source palette blue component intensities
// * @param alphaMode the alpha blending or mask mode, may be
// *        an integer 0-255 for global alpha; ignored if BLIT_ALPHA
// *        not specified in the blitter operations
// *        (see ALPHA_MODE_xxx constants)
// * @param alphaData the alpha blending or mask data, varies depending
// *        on the value of alphaMode and sometimes ignored
// * @param alphaStride the alpha data number of bytes per line
// * @param alphaX the top-left x-coord of the alpha blit region
// * @param alphaY the top-left y-coord of the alpha blit region
// * @param destData the destination byte array containing image data
// * @param destDepth the destination depth: one of 8, 16, 24, 32
// * @param destStride the destination number of bytes per line
// * @param destOrder the destination byte ordering: one of MSB_FIRST or LSB_FIRST;
// *        ignored if destDepth is not 16 or 32
// * @param destX the top-left x-coord of the destination blit region
// * @param destY the top-left y-coord of the destination blit region
// * @param destWidth the width of the destination blit region
// * @param destHeight the height of the destination blit region
// * @param destRedMask the destination red channel mask
// * @param destGreenMask the destination green channel mask
// * @param destBlueMask the destination blue channel mask
// * @param flipX if true the resulting image is flipped along the vertical axis
// * @param flipY if true the resulting image is flipped along the horizontal axis
// */
//static void blit(int op,
//    byte[] srcData, int srcDepth, int srcStride, int srcOrder,
//    int srcX, int srcY, int srcWidth, int srcHeight,
//    byte[] srcReds, byte[] srcGreens, byte[] srcBlues,
//    int alphaMode, byte[] alphaData, int alphaStride, int alphaX, int alphaY,
//    byte[] destData, int destDepth, int destStride, int destOrder,
//    int destX, int destY, int destWidth, int destHeight,
//    int destRedMask, int destGreenMask, int destBlueMask,
//    bool flipX, bool flipY) {
//    if ((destWidth <= 0) || (destHeight <= 0) || (alphaMode == ALPHA_TRANSPARENT)) return;

//    // these should be supplied as params later
//    int destAlphaMask = 0;

//    /*** Prepare scaling data ***/
//    int dwm1 = destWidth - 1;
//    int sfxi = (dwm1 != 0) ? (int)((((long)srcWidth << 16) - 1) / dwm1) : 0;
//    int dhm1 = destHeight - 1;
//    int sfyi = (dhm1 != 0) ? (int)((((long)srcHeight << 16) - 1) / dhm1) : 0;

//    /*** Prepare source-related data ***/
//    int stype;
//    switch (srcDepth) {
//        case 8:
//            stype = TYPE_INDEX_8;
//            break;
//        case 4:
//            srcStride <<= 1;
//            stype = TYPE_INDEX_4;
//            break;
//        case 2:
//            srcStride <<= 2;
//            stype = TYPE_INDEX_2;
//            break;
//        case 1:
//            srcStride <<= 3;
//            stype = (srcOrder == MSB_FIRST) ? TYPE_INDEX_1_MSB : TYPE_INDEX_1_LSB;
//            break;
//        default:
//            //throw new IllegalArgumentException("Invalid source type");
//            return;
//    }			
//    int spr = srcY * srcStride + srcX;

//    /*** Prepare destination-related data ***/
//    int dbpp, dtype;
//    switch (destDepth) {
//        case 8:
//            dbpp = 1;
//            dtype = TYPE_GENERIC_8;
//            break;
//        case 16:
//            dbpp = 2;
//            dtype = (destOrder == MSB_FIRST) ? TYPE_GENERIC_16_MSB : TYPE_GENERIC_16_LSB;
//            break;
//        case 24:
//            dbpp = 3;
//            dtype = TYPE_GENERIC_24;
//            break;
//        case 32:
//            dbpp = 4;
//            dtype = (destOrder == MSB_FIRST) ? TYPE_GENERIC_32_MSB : TYPE_GENERIC_32_LSB;
//            break;
//        default:
//            //throw new IllegalArgumentException("Invalid destination type");
//            return;
//    }			
//    int dpr = ((flipY) ? destY + dhm1 : destY) * destStride + ((flipX) ? destX + dwm1 : destX) * dbpp;
//    int dprxi = (flipX) ? -dbpp : dbpp;
//    int dpryi = (flipY) ? -destStride : destStride;

//    /*** Prepare special processing data ***/
//    int apr;
//    if ((op & BLIT_ALPHA) != 0) {
//        switch (alphaMode) {
//            case ALPHA_MASK_UNPACKED:
//            case ALPHA_CHANNEL_SEPARATE:
//                if (alphaData == null) alphaMode = 0x10000;
//                apr = alphaY * alphaStride + alphaX;
//                break;
//            case ALPHA_MASK_PACKED:
//                if (alphaData == null) alphaMode = 0x10000;
//                alphaStride <<= 3;
//                apr = alphaY * alphaStride + alphaX;
//                break;
//            case ALPHA_MASK_INDEX:
//            case ALPHA_MASK_RGB:
//                if (alphaData == null) alphaMode = 0x10000;
//                apr = 0;
//                break;
//            default:
//                alphaMode = (alphaMode << 16) / 255; // prescale
//            case ALPHA_CHANNEL_SOURCE:
//                apr = 0;
//                break;
//        }
//    } else {
//        alphaMode = 0x10000;
//        apr = 0;
//    }

//    /*** Comprehensive blit (apply transformations) ***/
//    int destRedShift = getChannelShift(destRedMask);
//    int destRedWidth = getChannelWidth(destRedMask, destRedShift);
//    byte[] destReds = ANY_TO_EIGHT[destRedWidth];
//    int destRedPreShift = 8 - destRedWidth;
//    int destGreenShift = getChannelShift(destGreenMask);
//    int destGreenWidth = getChannelWidth(destGreenMask, destGreenShift);
//    byte[] destGreens = ANY_TO_EIGHT[destGreenWidth];
//    int destGreenPreShift = 8 - destGreenWidth;
//    int destBlueShift = getChannelShift(destBlueMask);
//    int destBlueWidth = getChannelWidth(destBlueMask, destBlueShift);
//    byte[] destBlues = ANY_TO_EIGHT[destBlueWidth];
//    int destBluePreShift = 8 - destBlueWidth;
//    int destAlphaShift = getChannelShift(destAlphaMask);
//    int destAlphaWidth = getChannelWidth(destAlphaMask, destAlphaShift);
//    byte[] destAlphas = ANY_TO_EIGHT[destAlphaWidth];
//    int destAlphaPreShift = 8 - destAlphaWidth;

//    int dp = dpr;
//    int sp = spr;
//    int ap = apr, alpha = alphaMode;
//    int r = 0, g = 0, b = 0, a = 0, index = 0;
//    int rq = 0, gq = 0, bq = 0, aq = 0;
//    for (int dy = destHeight, sfy = sfyi; dy > 0; --dy,
//            sp = spr += (sfy >> 16) * srcStride,
//            ap = apr += (sfy >> 16) * alphaStride,
//            sfy = (sfy & 0xffff) + sfyi,
//            dp = dpr += dpryi) {
//        for (int dx = destWidth, sfx = sfxi; dx > 0; --dx,
//                dp += dprxi,
//                sfx = (sfx & 0xffff) + sfxi) {
//            /*** READ NEXT PIXEL ***/
//            switch (stype) {
//                case TYPE_INDEX_8:
//                    index = srcData[sp] & 0xff;
//                    sp += (sfx >> 16);
//                    break;
//                case TYPE_INDEX_4:
//                    if ((sp & 1) != 0) index = srcData[sp >> 1] & 0x0f;
//                    else index = (srcData[sp >> 1] >> 4) & 0x0f;
//                    sp += (sfx >> 16);
//                    break;
//                case TYPE_INDEX_2:
//                    index = (srcData[sp >> 2] >> (6 - (sp & 3) * 2)) & 0x03;
//                    sp += (sfx >> 16);
//                    break;
//                case TYPE_INDEX_1_MSB:
//                    index = (srcData[sp >> 3] >> (7 - (sp & 7))) & 0x01;
//                    sp += (sfx >> 16);
//                    break;
//                case TYPE_INDEX_1_LSB:
//                    index = (srcData[sp >> 3] >> (sp & 7)) & 0x01;
//                    sp += (sfx >> 16);
//                    break;
//            }

//            /*** DO SPECIAL PROCESSING IF REQUIRED ***/
//            r = srcReds[index] & 0xff;
//            g = srcGreens[index] & 0xff;
//            b = srcBlues[index] & 0xff;
//            switch (alphaMode) {
//                case ALPHA_CHANNEL_SEPARATE:
//                    alpha = ((alphaData[ap] & 0xff) << 16) / 255;
//                    ap += (sfx >> 16);
//                    break;
//                case ALPHA_MASK_UNPACKED:
//                    alpha = (alphaData[ap] != 0) ? 0x10000 : 0;
//                    ap += (sfx >> 16);
//                    break;						
//                case ALPHA_MASK_PACKED:
//                    alpha = (alphaData[ap >> 3] << ((ap & 7) + 9)) & 0x10000;
//                    ap += (sfx >> 16);
//                    break;
//                case ALPHA_MASK_INDEX: { // could speed up using binary search if we sorted the indices
//                    int i = 0;
//                    while (i < alphaData.Length) {
//                        if (index == (alphaData[i] & 0xff)) break;
//                    }
//                    if (i < alphaData.Length) continue;
//                } break;
//                case ALPHA_MASK_RGB: {
//                    int i = 0;
//                    while (i < alphaData.Length) {
//                        if ((r == (alphaData[i] & 0xff)) &&
//                            (g == (alphaData[i + 1] & 0xff)) &&
//                            (b == (alphaData[i + 2] & 0xff))) break;
//                        i += 3;
//                    }
//                    if (i < alphaData.Length) continue;
//                } break;
//            }
//            if (alpha != 0x10000) {
//                if (alpha == 0x0000) continue;
//                switch (dtype) {
//                    case TYPE_GENERIC_8: {
//                        int data = destData[dp] & 0xff;
//                        rq = destReds[(data & destRedMask) >> destRedShift] & 0xff;
//                        gq = destGreens[(data & destGreenMask) >> destGreenShift] & 0xff;
//                        bq = destBlues[(data & destBlueMask) >> destBlueShift] & 0xff;
//                        aq = destAlphas[(data & destAlphaMask) >> destAlphaShift] & 0xff;
//                    } break;
//                    case TYPE_GENERIC_16_MSB: {
//                        int data = ((destData[dp] & 0xff) << 8) | (destData[dp + 1] & 0xff);
//                        rq = destReds[(data & destRedMask) >> destRedShift] & 0xff;
//                        gq = destGreens[(data & destGreenMask) >> destGreenShift] & 0xff;
//                        bq = destBlues[(data & destBlueMask) >> destBlueShift] & 0xff;
//                        aq = destAlphas[(data & destAlphaMask) >> destAlphaShift] & 0xff;
//                    } break;
//                    case TYPE_GENERIC_16_LSB: {
//                        int data = ((destData[dp + 1] & 0xff) << 8) | (destData[dp] & 0xff);
//                        rq = destReds[(data & destRedMask) >> destRedShift] & 0xff;
//                        gq = destGreens[(data & destGreenMask) >> destGreenShift] & 0xff;
//                        bq = destBlues[(data & destBlueMask) >> destBlueShift] & 0xff;
//                        aq = destAlphas[(data & destAlphaMask) >> destAlphaShift] & 0xff;
//                    } break;
//                    case TYPE_GENERIC_24: {
//                        int data = (( ((destData[dp] & 0xff) << 8) |
//                            (destData[dp + 1] & 0xff)) << 8) |
//                            (destData[dp + 2] & 0xff);
//                        rq = destReds[(data & destRedMask) >> destRedShift] & 0xff;
//                        gq = destGreens[(data & destGreenMask) >> destGreenShift] & 0xff;
//                        bq = destBlues[(data & destBlueMask) >> destBlueShift] & 0xff;
//                        aq = destAlphas[(data & destAlphaMask) >> destAlphaShift] & 0xff;
//                    } break;
//                    case TYPE_GENERIC_32_MSB: {
//                        int data = (( (( ((destData[dp] & 0xff) << 8) |
//                            (destData[dp + 1] & 0xff)) << 8) |
//                            (destData[dp + 2] & 0xff)) << 8) |
//                            (destData[dp + 3] & 0xff);
//                        rq = destReds[(data & destRedMask) >> destRedShift] & 0xff;
//                        gq = destGreens[(data & destGreenMask) >> destGreenShift] & 0xff;
//                        bq = destBlues[(data & destBlueMask) >> destBlueShift] & 0xff;
//                        aq = destAlphas[(data & destAlphaMask) >> destAlphaShift] & 0xff;
//                    } break;
//                    case TYPE_GENERIC_32_LSB: {
//                        int data = (( (( ((destData[dp + 3] & 0xff) << 8) |
//                            (destData[dp + 2] & 0xff)) << 8) |
//                            (destData[dp + 1] & 0xff)) << 8) |
//                            (destData[dp] & 0xff);
//                        rq = destReds[(data & destRedMask) >> destRedShift] & 0xff;
//                        gq = destGreens[(data & destGreenMask) >> destGreenShift] & 0xff;
//                        bq = destBlues[(data & destBlueMask) >> destBlueShift] & 0xff;
//                        aq = destAlphas[(data & destAlphaMask) >> destAlphaShift] & 0xff;
//                    } break;
//                }
//                // Perform alpha blending
//                a = aq + ((a - aq) * alpha >> 16);
//                r = rq + ((r - rq) * alpha >> 16);
//                g = gq + ((g - gq) * alpha >> 16);
//                b = bq + ((b - bq) * alpha >> 16);
//            }

//            /*** WRITE NEXT PIXEL ***/
//            int data = 
//                (r >> destRedPreShift << destRedShift) |
//                (g >> destGreenPreShift << destGreenShift) |
//                (b >> destBluePreShift << destBlueShift) |
//                (a >> destAlphaPreShift << destAlphaShift);
//            switch (dtype) {
//                case TYPE_GENERIC_8: {
//                    destData[dp] = (byte) data;
//                } break;
//                case TYPE_GENERIC_16_MSB: {
//                    destData[dp] = (byte) (data >> 8);
//                    destData[dp + 1] = (byte) (data & 0xff);
//                } break;
//                case TYPE_GENERIC_16_LSB: {
//                    destData[dp] = (byte) (data & 0xff);
//                    destData[dp + 1] = (byte) (data >> 8);
//                } break;
//                case TYPE_GENERIC_24: {
//                    destData[dp] = (byte) (data >> 16);
//                    destData[dp + 1] = (byte) (data >> 8);
//                    destData[dp + 2] = (byte) (data & 0xff);
//                } break;
//                case TYPE_GENERIC_32_MSB: {
//                    destData[dp] = (byte) (data >> 24);
//                    destData[dp + 1] = (byte) (data >> 16);
//                    destData[dp + 2] = (byte) (data >> 8);
//                    destData[dp + 3] = (byte) (data & 0xff);
//                } break;
//                case TYPE_GENERIC_32_LSB: {
//                    destData[dp] = (byte) (data & 0xff);
//                    destData[dp + 1] = (byte) (data >> 8);
//                    destData[dp + 2] = (byte) (data >> 16);
//                    destData[dp + 3] = (byte) (data >> 24);
//                } break;
//            }
//        }
//    }			
//}

///**
// * Blits a direct palette image into an index palette image.
// * <p>
// * Note: The source and destination masks and palettes must
// * always be fully specified.
// * </p>
// * 
// * @param op the blitter operation: a combination of BLIT_xxx flags
// *        (see BLIT_xxx constants)
// * @param srcData the source byte array containing image data
// * @param srcDepth the source depth: one of 8, 16, 24, 32
// * @param srcStride the source number of bytes per line
// * @param srcOrder the source byte ordering: one of MSB_FIRST or LSB_FIRST;
// *        ignored if srcDepth is not 16 or 32
// * @param srcX the top-left x-coord of the source blit region
// * @param srcY the top-left y-coord of the source blit region
// * @param srcWidth the width of the source blit region
// * @param srcHeight the height of the source blit region
// * @param srcRedMask the source red channel mask
// * @param srcGreenMask the source green channel mask
// * @param srcBlueMask the source blue channel mask
// * @param alphaMode the alpha blending or mask mode, may be
// *        an integer 0-255 for global alpha; ignored if BLIT_ALPHA
// *        not specified in the blitter operations
// *        (see ALPHA_MODE_xxx constants)
// * @param alphaData the alpha blending or mask data, varies depending
// *        on the value of alphaMode and sometimes ignored
// * @param alphaStride the alpha data number of bytes per line
// * @param alphaX the top-left x-coord of the alpha blit region
// * @param alphaY the top-left y-coord of the alpha blit region
// * @param destData the destination byte array containing image data
// * @param destDepth the destination depth: one of 1, 2, 4, 8
// * @param destStride the destination number of bytes per line
// * @param destOrder the destination byte ordering: one of MSB_FIRST or LSB_FIRST;
// *        ignored if destDepth is not 1
// * @param destX the top-left x-coord of the destination blit region
// * @param destY the top-left y-coord of the destination blit region
// * @param destWidth the width of the destination blit region
// * @param destHeight the height of the destination blit region
// * @param destReds the destination palette red component intensities
// * @param destGreens the destination palette green component intensities
// * @param destBlues the destination palette blue component intensities
// * @param flipX if true the resulting image is flipped along the vertical axis
// * @param flipY if true the resulting image is flipped along the horizontal axis
// */
//static void blit(int op,
//    byte[] srcData, int srcDepth, int srcStride, int srcOrder,
//    int srcX, int srcY, int srcWidth, int srcHeight,
//    int srcRedMask, int srcGreenMask, int srcBlueMask,
//    int alphaMode, byte[] alphaData, int alphaStride, int alphaX, int alphaY,
//    byte[] destData, int destDepth, int destStride, int destOrder,
//    int destX, int destY, int destWidth, int destHeight,
//    byte[] destReds, byte[] destGreens, byte[] destBlues,
//    bool flipX, bool flipY) {
//    if ((destWidth <= 0) || (destHeight <= 0) || (alphaMode == ALPHA_TRANSPARENT)) return;

//    // these should be supplied as params later
//    int srcAlphaMask = 0;

//    /*** Prepare scaling data ***/
//    int dwm1 = destWidth - 1;
//    int sfxi = (dwm1 != 0) ? (int)((((long)srcWidth << 16) - 1) / dwm1) : 0;
//    int dhm1 = destHeight - 1;
//    int sfyi = (dhm1 != 0) ? (int)((((long)srcHeight << 16) - 1) / dhm1) : 0;

//    /*** Prepare source-related data ***/
//    int sbpp, stype;
//    switch (srcDepth) {
//        case 8:
//            sbpp = 1;
//            stype = TYPE_GENERIC_8;
//            break;
//        case 16:
//            sbpp = 2;
//            stype = (srcOrder == MSB_FIRST) ? TYPE_GENERIC_16_MSB : TYPE_GENERIC_16_LSB;
//            break;
//        case 24:
//            sbpp = 3;
//            stype = TYPE_GENERIC_24;
//            break;
//        case 32:
//            sbpp = 4;
//            stype = (srcOrder == MSB_FIRST) ? TYPE_GENERIC_32_MSB : TYPE_GENERIC_32_LSB;
//            break;
//        default:
//            //throw new IllegalArgumentException("Invalid source type");
//            return;
//    }			
//    int spr = srcY * srcStride + srcX * sbpp;

//    /*** Prepare destination-related data ***/
//    int dtype;
//    switch (destDepth) {
//        case 8:
//            dtype = TYPE_INDEX_8;
//            break;
//        case 4:
//            destStride <<= 1;
//            dtype = TYPE_INDEX_4;
//            break;
//        case 2:
//            destStride <<= 2;
//            dtype = TYPE_INDEX_2;
//            break;
//        case 1:
//            destStride <<= 3;
//            dtype = (destOrder == MSB_FIRST) ? TYPE_INDEX_1_MSB : TYPE_INDEX_1_LSB;
//            break;
//        default:
//            //throw new IllegalArgumentException("Invalid source type");
//            return;
//    }			
//    int dpr = ((flipY) ? destY + dhm1 : destY) * destStride + ((flipX) ? destX + dwm1 : destX);
//    int dprxi = (flipX) ? -1 : 1;
//    int dpryi = (flipY) ? -destStride : destStride;

//    /*** Prepare special processing data ***/
//    int apr;
//    if ((op & BLIT_ALPHA) != 0) {
//        switch (alphaMode) {
//            case ALPHA_MASK_UNPACKED:
//            case ALPHA_CHANNEL_SEPARATE:
//                if (alphaData == null) alphaMode = 0x10000;
//                apr = alphaY * alphaStride + alphaX;
//                break;
//            case ALPHA_MASK_PACKED:
//                if (alphaData == null) alphaMode = 0x10000;
//                alphaStride <<= 3;
//                apr = alphaY * alphaStride + alphaX;
//                break;
//            case ALPHA_MASK_INDEX:
//                //throw new IllegalArgumentException("Invalid alpha type");
//                return;
//            case ALPHA_MASK_RGB:
//                if (alphaData == null) alphaMode = 0x10000;
//                apr = 0;
//                break;
//            default:
//                alphaMode = (alphaMode << 16) / 255; // prescale
//            case ALPHA_CHANNEL_SOURCE:
//                apr = 0;
//                break;
//        }
//    } else {
//        alphaMode = 0x10000;
//        apr = 0;
//    }
//    bool ditherEnabled = (op & BLIT_DITHER) != 0;

//    /*** Comprehensive blit (apply transformations) ***/
//    int srcRedShift = getChannelShift(srcRedMask);
//    byte[] srcReds = ANY_TO_EIGHT[getChannelWidth(srcRedMask, srcRedShift)];
//    int srcGreenShift = getChannelShift(srcGreenMask);
//    byte[] srcGreens = ANY_TO_EIGHT[getChannelWidth(srcGreenMask, srcGreenShift)];
//    int srcBlueShift = getChannelShift(srcBlueMask);
//    byte[] srcBlues = ANY_TO_EIGHT[getChannelWidth(srcBlueMask, srcBlueShift)];
//    int srcAlphaShift = getChannelShift(srcAlphaMask);
//    byte[] srcAlphas = ANY_TO_EIGHT[getChannelWidth(srcAlphaMask, srcAlphaShift)];

//    int dp = dpr;
//    int sp = spr;
//    int ap = apr, alpha = alphaMode;
//    int r = 0, g = 0, b = 0, a = 0;
//    int indexq = 0;
//    int lastindex = 0, lastr = -1, lastg = -1, lastb = -1;
//    int[] rerr, gerr, berr;
//    int destPaletteSize = 1 << destDepth;
//    if ((destReds != null) && (destReds.Length < destPaletteSize)) destPaletteSize = destReds.Length;
//    if (ditherEnabled) {
//        rerr = new int[destWidth + 2];
//        gerr = new int[destWidth + 2];
//        berr = new int[destWidth + 2];
//    } else {
//        rerr = null; gerr = null; berr = null;
//    }
//    for (int dy = destHeight, sfy = sfyi; dy > 0; --dy,
//            sp = spr += (sfy >> 16) * srcStride,
//            ap = apr += (sfy >> 16) * alphaStride,
//            sfy = (sfy & 0xffff) + sfyi,
//            dp = dpr += dpryi) {
//        int lrerr = 0, lgerr = 0, lberr = 0;
//        for (int dx = destWidth, sfx = sfxi; dx > 0; --dx,
//                dp += dprxi,
//                sfx = (sfx & 0xffff) + sfxi) {
//            /*** READ NEXT PIXEL ***/
//            switch (stype) {
//                case TYPE_GENERIC_8: {
//                    int data = srcData[sp] & 0xff;
//                    sp += (sfx >> 16);
//                    r = srcReds[(data & srcRedMask) >> srcRedShift] & 0xff;
//                    g = srcGreens[(data & srcGreenMask) >> srcGreenShift] & 0xff;
//                    b = srcBlues[(data & srcBlueMask) >> srcBlueShift] & 0xff;
//                    a = srcAlphas[(data & srcAlphaMask) >> srcAlphaShift] & 0xff;
//                } break;
//                case TYPE_GENERIC_16_MSB: {
//                    int data = ((srcData[sp] & 0xff) << 8) | (srcData[sp + 1] & 0xff);
//                    sp += (sfx >> 16) * 2;
//                    r = srcReds[(data & srcRedMask) >> srcRedShift] & 0xff;
//                    g = srcGreens[(data & srcGreenMask) >> srcGreenShift] & 0xff;
//                    b = srcBlues[(data & srcBlueMask) >> srcBlueShift] & 0xff;
//                    a = srcAlphas[(data & srcAlphaMask) >> srcAlphaShift] & 0xff;
//                } break;
//                case TYPE_GENERIC_16_LSB: {
//                    int data = ((srcData[sp + 1] & 0xff) << 8) | (srcData[sp] & 0xff);
//                    sp += (sfx >> 16) * 2;
//                    r = srcReds[(data & srcRedMask) >> srcRedShift] & 0xff;
//                    g = srcGreens[(data & srcGreenMask) >> srcGreenShift] & 0xff;
//                    b = srcBlues[(data & srcBlueMask) >> srcBlueShift] & 0xff;
//                    a = srcAlphas[(data & srcAlphaMask) >> srcAlphaShift] & 0xff;
//                } break;
//                case TYPE_GENERIC_24: {
//                    int data = (( ((srcData[sp] & 0xff) << 8) |
//                        (srcData[sp + 1] & 0xff)) << 8) |
//                        (srcData[sp + 2] & 0xff);
//                    sp += (sfx >> 16) * 3;
//                    r = srcReds[(data & srcRedMask) >> srcRedShift] & 0xff;
//                    g = srcGreens[(data & srcGreenMask) >> srcGreenShift] & 0xff;
//                    b = srcBlues[(data & srcBlueMask) >> srcBlueShift] & 0xff;
//                    a = srcAlphas[(data & srcAlphaMask) >> srcAlphaShift] & 0xff;
//                } break;
//                case TYPE_GENERIC_32_MSB: {
//                    int data = (( (( ((srcData[sp] & 0xff) << 8) |
//                        (srcData[sp + 1] & 0xff)) << 8) |
//                        (srcData[sp + 2] & 0xff)) << 8) |
//                        (srcData[sp + 3] & 0xff);
//                    sp += (sfx >> 16) * 4;
//                    r = srcReds[(data & srcRedMask) >> srcRedShift] & 0xff;
//                    g = srcGreens[(data & srcGreenMask) >> srcGreenShift] & 0xff;
//                    b = srcBlues[(data & srcBlueMask) >> srcBlueShift] & 0xff;
//                    a = srcAlphas[(data & srcAlphaMask) >> srcAlphaShift] & 0xff;
//                } break;
//                case TYPE_GENERIC_32_LSB: {
//                    int data = (( (( ((srcData[sp + 3] & 0xff) << 8) |
//                        (srcData[sp + 2] & 0xff)) << 8) |
//                        (srcData[sp + 1] & 0xff)) << 8) |
//                        (srcData[sp] & 0xff);
//                    sp += (sfx >> 16) * 4;
//                    r = srcReds[(data & srcRedMask) >> srcRedShift] & 0xff;
//                    g = srcGreens[(data & srcGreenMask) >> srcGreenShift] & 0xff;
//                    b = srcBlues[(data & srcBlueMask) >> srcBlueShift] & 0xff;
//                    a = srcAlphas[(data & srcAlphaMask) >> srcAlphaShift] & 0xff;
//                } break;
//            }

//            /*** DO SPECIAL PROCESSING IF REQUIRED ***/
//            switch (alphaMode) {
//                case ALPHA_CHANNEL_SEPARATE:
//                    alpha = ((alphaData[ap] & 0xff) << 16) / 255;
//                    ap += (sfx >> 16);
//                    break;
//                case ALPHA_CHANNEL_SOURCE:
//                    alpha = (a << 16) / 255;
//                    break;
//                case ALPHA_MASK_UNPACKED:
//                    alpha = (alphaData[ap] != 0) ? 0x10000 : 0;
//                    ap += (sfx >> 16);
//                    break;						
//                case ALPHA_MASK_PACKED:
//                    alpha = (alphaData[ap >> 3] << ((ap & 7) + 9)) & 0x10000;
//                    ap += (sfx >> 16);
//                    break;
//                case ALPHA_MASK_RGB:
//                    alpha = 0x10000;
//                    for (int i = 0; i < alphaData.Length; i += 3) {
//                        if ((r == alphaData[i]) && (g == alphaData[i + 1]) && (b == alphaData[i + 2])) {
//                            alpha = 0x0000;
//                            break;
//                        }
//                    }
//                    break;
//            }
//            if (alpha != 0x10000) {
//                if (alpha == 0x0000) continue;
//                switch (dtype) {
//                    case TYPE_INDEX_8:
//                        indexq = destData[dp] & 0xff;
//                        break;
//                    case TYPE_INDEX_4:
//                        if ((dp & 1) != 0) indexq = destData[dp >> 1] & 0x0f;
//                        else indexq = (destData[dp >> 1] >> 4) & 0x0f;
//                        break;
//                    case TYPE_INDEX_2:
//                        indexq = (destData[dp >> 2] >> (6 - (dp & 3) * 2)) & 0x03;
//                        break;
//                    case TYPE_INDEX_1_MSB:
//                        indexq = (destData[dp >> 3] >> (7 - (dp & 7))) & 0x01;
//                        break;
//                    case TYPE_INDEX_1_LSB:
//                        indexq = (destData[dp >> 3] >> (dp & 7)) & 0x01;
//                        break;
//                }
//                // Perform alpha blending
//                int rq = destReds[indexq] & 0xff;
//                int gq = destGreens[indexq] & 0xff;
//                int bq = destBlues[indexq] & 0xff;
//                r = rq + ((r - rq) * alpha >> 16);
//                g = gq + ((g - gq) * alpha >> 16);
//                b = bq + ((b - bq) * alpha >> 16);
//            }

//            /*** MAP COLOR TO THE PALETTE ***/
//            if (ditherEnabled) {
//                // Floyd-Steinberg error diffusion
//                r += rerr[dx] >> 4;
//                if (r < 0) r = 0; else if (r > 255) r = 255;
//                g += gerr[dx] >> 4;
//                if (g < 0) g = 0; else if (g > 255) g = 255;
//                b += berr[dx] >> 4;
//                if (b < 0) b = 0; else if (b > 255) b = 255;
//                rerr[dx] = lrerr;
//                gerr[dx] = lgerr;
//                berr[dx] = lberr;
//            }
//            if (r != lastr || g != lastg || b != lastb) {
//                // moving the variable declarations out seems to make the JDK JIT happier...
//                for (int j = 0, dr, dg, db, distance, minDistance = 0x7fffffff; j < destPaletteSize; ++j) {
//                    dr = (destReds[j] & 0xff) - r;
//                    dg = (destGreens[j] & 0xff) - g;
//                    db = (destBlues[j] & 0xff) - b;
//                    distance = dr * dr + dg * dg + db * db;
//                    if (distance < minDistance) {
//                        lastindex = j;
//                        if (distance == 0) break;
//                        minDistance = distance;
//                    }
//                }
//                lastr = r; lastg = g; lastb = b;
//            }
//            if (ditherEnabled) {
//                // Floyd-Steinberg error diffusion, cont'd...
//                int dxm1 = dx - 1, dxp1 = dx + 1;
//                int acc;
//                rerr[dxp1] += acc = (lrerr = r - (destReds[lastindex] & 0xff)) + lrerr + lrerr;
//                rerr[dx] += acc += lrerr + lrerr;
//                rerr[dxm1] += acc + lrerr + lrerr;
//                gerr[dxp1] += acc = (lgerr = g - (destGreens[lastindex] & 0xff)) + lgerr + lgerr;
//                gerr[dx] += acc += lgerr + lgerr;
//                gerr[dxm1] += acc + lgerr + lgerr;
//                berr[dxp1] += acc = (lberr = b - (destBlues[lastindex] & 0xff)) + lberr + lberr;
//                berr[dx] += acc += lberr + lberr;
//                berr[dxm1] += acc + lberr + lberr;
//            }

//            /*** WRITE NEXT PIXEL ***/
//            switch (dtype) {
//                case TYPE_INDEX_8:
//                    destData[dp] = (byte) lastindex;
//                    break;
//                case TYPE_INDEX_4:
//                    if ((dp & 1) != 0) destData[dp >> 1] = (byte)((destData[dp >> 1] & 0xf0) | lastindex);
//                    else destData[dp >> 1] = (byte)((destData[dp >> 1] & 0x0f) | (lastindex << 4));
//                    break;
//                case TYPE_INDEX_2: {
//                    int shift = 6 - (dp & 3) * 2;
//                    destData[dp >> 2] = (byte)(destData[dp >> 2] & ~(0x03 << shift) | (lastindex << shift));
//                } break;					
//                case TYPE_INDEX_1_MSB: {
//                    int shift = 7 - (dp & 7);
//                    destData[dp >> 3] = (byte)(destData[dp >> 3] & ~(0x01 << shift) | (lastindex << shift));
//                } break;
//                case TYPE_INDEX_1_LSB: {
//                    int shift = dp & 7;
//                    destData[dp >> 3] = (byte)(destData[dp >> 3] & ~(0x01 << shift) | (lastindex << shift));
//                } break;					
//            }
//        }
//    }
//}

///**
// * Computes the required channel shift from a mask.
// */
//static int getChannelShift(int mask) {
//    if (mask == 0) return 0;
//    int i;
//    for (i = 0; ((mask & 1) == 0) && (i < 32); ++i) {
//        mask >>= 1;
//    }
//    return i;
//}

///**
// * Computes the required channel width (depth) from a mask.
// */
//static int getChannelWidth(int mask, int shift) {
//    if (mask == 0) return 0;
//    int i;
//    mask >>= shift;
//    for (i = shift; ((mask & 1) != 0) && (i < 32); ++i) {
//        mask >>= 1;
//    }
//    return i - shift;
//}

///**
// * Extracts a field from packed RGB data given a mask for that field.
// */
//static byte getChannelField(int data, int mask) {
//    int shift = getChannelShift(mask);
//    return ANY_TO_EIGHT[getChannelWidth(mask, shift)][(data & mask) >> shift];
//}

///**
// * Creates an ImageData containing one band's worth of a gradient filled
// * block.  If <code>vertical</code> is true, the band must be tiled
// * horizontally to fill a region, otherwise it must be tiled vertically.
// *
// * @param width the width of the region to be filled
// * @param height the height of the region to be filled
// * @param vertical if true sweeps from top to bottom, else
// *        sweeps from left to right
// * @param fromRGB the color to start with
// * @param toRGB the color to end with
// * @param redBits the number of significant red bits, 0 for palette modes
// * @param greenBits the number of significant green bits, 0 for palette modes
// * @param blueBits the number of significant blue bits, 0 for palette modes
// * @return the new ImageData
// */
//static ImageData createGradientBand(
//    int width, int height, bool vertical,
//    RGB fromRGB, RGB toRGB,
//    int redBits, int greenBits, int blueBits) {
//    /* Gradients are drawn as tiled bands */
//    int bandWidth, bandHeight, bitmapDepth;
//    byte[] bitmapData;
//    PaletteData paletteData;
//    /* Select an algorithm depending on the depth of the screen */
//    if (redBits != 0 && greenBits != 0 && blueBits != 0) {
//        paletteData = new PaletteData(0x0000ff00, 0x00ff0000, 0xff000000);
//        bitmapDepth = 32;
//        if (redBits >= 8 && greenBits >= 8 && blueBits >= 8) {
//            /* Precise color */
//            int steps;
//            if (vertical) {
//                bandWidth = 1;
//                bandHeight = height;
//                steps = bandHeight > 1 ? bandHeight - 1 : 1;
//            } else {
//                bandWidth = width;
//                bandHeight = 1;
//                steps = bandWidth > 1 ? bandWidth - 1 : 1;
//            }
//            int bytesPerLine = bandWidth * 4;
//            bitmapData = new byte[bandHeight * bytesPerLine];
//            buildPreciseGradientChannel(fromRGB.blue, toRGB.blue, steps, bandWidth, bandHeight, vertical, bitmapData, 0, bytesPerLine);
//            buildPreciseGradientChannel(fromRGB.green, toRGB.green, steps, bandWidth, bandHeight, vertical, bitmapData, 1, bytesPerLine);
//            buildPreciseGradientChannel(fromRGB.red, toRGB.red, steps, bandWidth, bandHeight, vertical, bitmapData, 2, bytesPerLine);
//        } else {
//            /* Dithered color */
//            int steps;
//            if (vertical) {
//                bandWidth = (width < 8) ? width : 8;
//                bandHeight = height;
//                steps = bandHeight > 1 ? bandHeight - 1 : 1;
//            } else {
//                bandWidth = width;
//                bandHeight = (height < 8) ? height : 8;
//                steps = bandWidth > 1 ? bandWidth - 1 : 1;
//            }
//            int bytesPerLine = bandWidth * 4;
//            bitmapData = new byte[bandHeight * bytesPerLine];
//            buildDitheredGradientChannel(fromRGB.blue, toRGB.blue, steps, bandWidth, bandHeight, vertical, bitmapData, 0, bytesPerLine, blueBits);
//            buildDitheredGradientChannel(fromRGB.green, toRGB.green, steps, bandWidth, bandHeight, vertical, bitmapData, 1, bytesPerLine, greenBits);
//            buildDitheredGradientChannel(fromRGB.red, toRGB.red, steps, bandWidth, bandHeight, vertical, bitmapData, 2, bytesPerLine, redBits);			
//        }
//    } else {
//        /* Dithered two tone */
//        paletteData = new PaletteData(new RGB[] { fromRGB, toRGB });
//        bitmapDepth = 8;
//        int blendi;
//        if (vertical) {
//            bandWidth = (width < 8) ? width : 8;
//            bandHeight = height;
//            blendi = (bandHeight > 1) ? 0x1040000 / (bandHeight - 1) + 1 : 1;
//        } else {
//            bandWidth = width;
//            bandHeight = (height < 8) ? height : 8;
//            blendi = (bandWidth > 1) ? 0x1040000 / (bandWidth - 1) + 1 : 1;
//        }
//        int bytesPerLine = (bandWidth + 3) & -4;
//        bitmapData = new byte[bandHeight * bytesPerLine];
//        if (vertical) {
//            for (int dy = 0, blend = 0, dp = 0; dy < bandHeight;
//                ++dy, blend += blendi, dp += bytesPerLine) {
//                for (int dx = 0; dx < bandWidth; ++dx) {
//                    bitmapData[dp + dx] = (blend + DITHER_MATRIX[dy & 7][dx]) <
//                        0x1000000 ? (byte)0 : (byte)1;
//                }
//            }		
//        } else {
//            for (int dx = 0, blend = 0; dx < bandWidth; ++dx, blend += blendi) {
//                for (int dy = 0, dptr = dx; dy < bandHeight; ++dy, dptr += bytesPerLine) {
//                    bitmapData[dptr] = (blend + DITHER_MATRIX[dy][dx & 7]) <
//                        0x1000000 ? (byte)0 : (byte)1;
//                }
//            }
//        }
//    }
//    return new ImageData(bandWidth, bandHeight, bitmapDepth, paletteData, 4, bitmapData);
//}

///* 
// * Fill in gradated values for a color channel
// */
//static void buildPreciseGradientChannel(int from, int to, int steps,
//    int bandWidth, int bandHeight, bool vertical,
//    byte[] bitmapData, int dp, int bytesPerLine) {
//    int val = from << 16;
//    int inc = ((to << 16) - val) / steps + 1;
//    if (vertical) {
//        for (int dy = 0; dy < bandHeight; ++dy, dp += bytesPerLine) {
//            bitmapData[dp] = (byte)(val >> 16);
//            val += inc;
//        }
//    } else {
//        for (int dx = 0; dx < bandWidth; ++dx, dp += 4) {
//            bitmapData[dp] = (byte)(val >> 16);
//            val += inc;
//        }
//    }		
//}

///* 
// * Fill in dithered gradated values for a color channel
// */
//static void buildDitheredGradientChannel(int from, int to, int steps,
//    int bandWidth, int bandHeight, bool vertical,
//    byte[] bitmapData, int dp, int bytesPerLine, int bits) {
//    int mask = 0xff00 >> bits;
//    int val = from << 16;
//    int inc = ((to << 16) - val) / steps + 1;
//    if (vertical) {
//        for (int dy = 0; dy < bandHeight; ++dy, dp += bytesPerLine) {
//            for (int dx = 0, dptr = dp; dx < bandWidth; ++dx, dptr += 4) {
//                int thresh = DITHER_MATRIX[dy & 7][dx] >> bits;
//                int temp = val + thresh;
//                if (temp > 0xffffff) bitmapData[dptr] = -1;
//                else bitmapData[dptr] = (byte)((temp >> 16) & mask);
//            }
//            val += inc;
//        }
//    } else {
//        for (int dx = 0; dx < bandWidth; ++dx, dp += 4) {
//            for (int dy = 0, dptr = dp; dy < bandHeight; ++dy, dptr += bytesPerLine) {
//                int thresh = DITHER_MATRIX[dy][dx & 7] >> bits;
//                int temp = val + thresh;
//                if (temp > 0xffffff) bitmapData[dptr] = -1;
//                else bitmapData[dptr] = (byte)((temp >> 16) & mask);
//            }
//            val += inc;
//        }
//    }
//}

///**
// * Renders a gradient onto a GC.
// * <p>
// * This is a GC helper.
// * </p>
// *
// * @param gc the GC to render the gradient onto
// * @param device the device the GC belongs to
// * @param x the top-left x coordinate of the region to be filled
// * @param y the top-left y coordinate of the region to be filled
// * @param width the width of the region to be filled
// * @param height the height of the region to be filled
// * @param vertical if true sweeps from top to bottom, else
// *        sweeps from left to right
// * @param fromRGB the color to start with
// * @param toRGB the color to end with
// * @param redBits the number of significant red bits, 0 for palette modes
// * @param greenBits the number of significant green bits, 0 for palette modes
// * @param blueBits the number of significant blue bits, 0 for palette modes
// */
//static void fillGradientRectangle(GC gc, Device device,
//    int x, int y, int width, int height, bool vertical,
//    RGB fromRGB, RGB toRGB,
//    int redBits, int greenBits, int blueBits) {
//    /* Create the bitmap and tile it */
//    ImageData band = createGradientBand(width, height, vertical,
//        fromRGB, toRGB, redBits, greenBits, blueBits);
//    Image image = new Image(device, band);
//    if ((band.width == 1) || (band.height == 1)) {
//        gc.drawImage(image, 0, 0, band.width, band.height, x, y, width, height);
//    } else {
//        if (vertical) {
//            for (int dx = 0; dx < width; dx += band.width) {
//                int blitWidth = width - dx;
//                if (blitWidth > band.width) blitWidth = band.width;
//                gc.drawImage(image, 0, 0, blitWidth, band.height, dx + x, y, blitWidth, band.height);
//            }
//        } else {
//            for (int dy = 0; dy < height; dy += band.height) {
//                int blitHeight = height - dy;
//                if (blitHeight > band.height) blitHeight = band.height;
//                gc.drawImage(image, 0, 0, band.width, blitHeight, x, dy + y, band.width, blitHeight);
//            }
//        }
//    }
//    image.dispose();
//}

//}
//}
